Browse Source

Merge branch 'giza-protobuf-and-query-node' into distributor-node

Leszek Wiesner 3 years ago
parent
commit
9a9dbec3ce
75 changed files with 3537 additions and 6549 deletions
  1. 12 12
      Cargo.lock
  2. 3 0
      devops/infrastructure/node-network/Pulumi.yaml
  3. 12 1
      devops/infrastructure/node-network/README.md
  4. 26 7
      devops/infrastructure/node-network/index.ts
  5. 0 16
      metadata-protobuf/compile.sh
  6. 0 1723
      metadata-protobuf/compiled/index.d.ts
  7. 0 4268
      metadata-protobuf/compiled/index.js
  8. 3 1
      metadata-protobuf/package.json
  9. 19 1
      metadata-protobuf/proto/Storage.proto
  10. 4 0
      metadata-protobuf/scripts/compile.ts
  11. 6 0
      metadata-protobuf/src/utils.ts
  12. 21 4
      node/src/chain_spec/mod.rs
  13. 13 22
      pioneer/packages/joy-forum/src/ForumRoot.tsx
  14. 78 14
      pioneer/packages/joy-forum/src/ViewThread.tsx
  15. 3 7
      pioneer/packages/joy-utils/src/transport/proposals.ts
  16. 15 11
      query-node/mappings/content/utils.ts
  17. 1 1
      query-node/mappings/storage/index.ts
  18. 65 16
      query-node/mappings/storage/metadata.ts
  19. 4 1
      query-node/mappings/workingGroup.ts
  20. 41 4
      query-node/schemas/storage.graphql
  21. 8 2
      runtime-modules/common/src/working_group.rs
  22. 1 1
      runtime-modules/content/Cargo.toml
  23. 6 13
      runtime-modules/content/src/lib.rs
  24. 7 41
      runtime-modules/content/src/permissions/mod.rs
  25. 0 2
      runtime-modules/content/src/tests/mock.rs
  26. 1 1
      runtime-modules/forum/Cargo.toml
  27. 1 1
      runtime-modules/governance/Cargo.toml
  28. 5 2
      runtime-modules/governance/src/mock.rs
  29. 1 1
      runtime-modules/hiring/Cargo.toml
  30. 1 1
      runtime-modules/membership/Cargo.toml
  31. 22 40
      runtime-modules/membership/src/lib.rs
  32. 5 2
      runtime-modules/membership/src/mock.rs
  33. 1 1
      runtime-modules/memo/Cargo.toml
  34. 1 1
      runtime-modules/proposals/codex/src/lib.rs
  35. 5 2
      runtime-modules/proposals/codex/src/tests/mock.rs
  36. 1 1
      runtime-modules/proposals/discussion/Cargo.toml
  37. 1 1
      runtime-modules/proposals/discussion/src/lib.rs
  38. 5 2
      runtime-modules/proposals/discussion/src/tests/mock.rs
  39. 1 1
      runtime-modules/proposals/engine/Cargo.toml
  40. 1 1
      runtime-modules/proposals/engine/src/lib.rs
  41. 5 2
      runtime-modules/proposals/engine/src/tests/mock/mod.rs
  42. 1 1
      runtime-modules/recurring-reward/Cargo.toml
  43. 1 1
      runtime-modules/stake/Cargo.toml
  44. 2 2
      runtime-modules/storage/src/lib.rs
  45. 5 2
      runtime-modules/storage/src/tests/mocks.rs
  46. 1 1
      runtime-modules/token-minting/Cargo.toml
  47. 1 1
      runtime-modules/working-group/Cargo.toml
  48. 2 2
      runtime-modules/working-group/src/lib.rs
  49. 5 2
      runtime-modules/working-group/src/tests/mock.rs
  50. 1 1
      runtime/src/integration/proposals/membership_origin_validator.rs
  51. 9 1
      runtime/src/integration/proposals/proposal_encoder.rs
  52. 88 156
      runtime/src/integration/working_group.rs
  53. 35 11
      runtime/src/lib.rs
  54. 0 4
      runtime/src/primitives.rs
  55. 169 45
      runtime/src/tests/proposals_integration/working_group_proposals.rs
  56. 1 1
      types/augment-codec/all.ts
  57. 13 1
      types/augment-codec/augment-api-consts.ts
  58. 797 1
      types/augment-codec/augment-api-errors.ts
  59. 267 5
      types/augment-codec/augment-api-events.ts
  60. 127 1
      types/augment-codec/augment-api-query.ts
  61. 168 6
      types/augment-codec/augment-api-tx.ts
  62. 0 0
      types/augment-codec/augment-types.ts
  63. 4 3
      types/augment/all/defs.json
  64. 3 4
      types/augment/all/types.ts
  65. 13 1
      types/augment/augment-api-consts.ts
  66. 797 1
      types/augment/augment-api-errors.ts
  67. 267 5
      types/augment/augment-api-events.ts
  68. 127 1
      types/augment/augment-api-query.ts
  69. 168 6
      types/augment/augment-api-tx.ts
  70. 0 0
      types/augment/augment-types.ts
  71. 1 1
      types/src/JoyEnum.ts
  72. 9 24
      types/src/common.ts
  73. 1 1
      types/src/index.ts
  74. 40 29
      types/src/scripts/generateRegistryJson.ts
  75. 9 0
      yarn.lock

+ 12 - 12
Cargo.lock

@@ -3822,7 +3822,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-content"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3859,7 +3859,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-forum"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3876,7 +3876,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-governance"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3919,7 +3919,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-hiring"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3957,7 +3957,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-membership"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3975,7 +3975,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-memo"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4054,7 +4054,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-proposals-discussion"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4072,7 +4072,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-proposals-engine"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4106,7 +4106,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-recurring-reward"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4157,7 +4157,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-stake"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4259,7 +4259,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-token-mint"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4337,7 +4337,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-working-group"
-version = "3.1.1"
+version = "3.2.0"
 dependencies = [
  "frame-support",
  "frame-system",

+ 3 - 0
devops/infrastructure/node-network/Pulumi.yaml

@@ -22,3 +22,6 @@ template:
     nodeImage:
       description: Docker image with tag to be used as validator and RPC nodes
       default: 'joystream/node:latest'
+    encryptionKey:
+      description: Key to encrypt the 7z containing secrets with
+      default: '1234'

+ 12 - 1
devops/infrastructure/node-network/README.md

@@ -39,7 +39,7 @@ After cloning this repo, from this working directory, run these commands:
    ```bash
    $ pulumi config set-all --plaintext aws:region=us-east-1 --plaintext aws:profile=joystream-user \
     --plaintext numberOfValidators=2 --plaintext isMinikube=true --plaintext networkSuffix=8122 \
-    --plaintext nodeImage=joystream/node:latest
+    --plaintext nodeImage=joystream/node:latest --plaintext encryptionKey=password
    ```
 
    If you want to build the stack on AWS set the `isMinikube` config to `false`
@@ -67,6 +67,11 @@ After cloning this repo, from this working directory, run these commands:
 
    The ws-rpc endpoint is `https://<ENDPOINT>/ws-rpc` and http-rpc endpoint is `https://<ENDPOINT>/http-rpc`
 
+1. If you are using Minikube, run `minikube service node-network -n $(pulumi stack output namespaceName)`
+
+   This will setup a proxy for your `node-network` service, which can then be accessed at
+   the URL given in the output
+
 1. Access the Kubernetes Cluster using `kubectl`
 
    To access your new Kubernetes cluster using `kubectl`, we need to set up the
@@ -106,6 +111,12 @@ After cloning this repo, from this working directory, run these commands:
    $ kubectl exec --stdin --tty <PODNAME> -c colossus -- /bin/bash
    ```
 
+1. To get the chain-data and secrets, run the below command
+
+   ```bash
+   $ kubectl cp $(kubectl get pods | grep rpc-node | awk '{print $1}'):/chain-data/chain-data.7z ./chain-data.7z
+   ```
+
 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
 
    ```bash

+ 26 - 7
devops/infrastructure/node-network/index.ts

@@ -57,6 +57,7 @@ const numberOfValidators = config.getNumber('numberOfValidators') || 1
 const chainDataPath = '/chain-data'
 const chainSpecPath = `${chainDataPath}/chainspec-raw.json`
 const nodeImage = config.get('nodeImage') || 'joystream/node:latest'
+const encryptKey = config.get('encryptionKey') || '1234'
 
 const subkeyContainers = getSubkeyContainers(numberOfValidators, chainDataPath)
 let pvcClaimName: pulumi.Output<any>
@@ -178,6 +179,18 @@ const chainDataPrepareJob = new k8s.batch.v1.Job(
                 },
               ],
             },
+            {
+              name: '7z',
+              image: 'danielwhatmuff/7z-docker',
+              command: ['/bin/sh', '-c'],
+              args: [`7z a -p${encryptKey} ${chainDataPath}/chain-data.7z ${chainDataPath}/*`],
+              volumeMounts: [
+                {
+                  name: 'config-data',
+                  mountPath: chainDataPath,
+                },
+              ],
+            },
           ],
           volumes: [
             {
@@ -289,6 +302,7 @@ const service = new k8s.core.v1.Service(
       name: 'node-network',
     },
     spec: {
+      type: isMinikube ? 'NodePort' : 'ClusterIP',
       ports: [
         { name: 'port-1', port: 9944 },
         { name: 'port-2', port: 9933 },
@@ -313,11 +327,16 @@ const caddyEndpoints = [
 }`,
 ]
 
-const caddy = new CaddyServiceDeployment(
-  'caddy-proxy',
-  { lbReady, namespaceName: namespaceName, isMinikube, caddyEndpoints },
-  resourceOptions
-)
+export let endpoint1: pulumi.Output<string>
+export let endpoint2: pulumi.Output<string>
 
-export const endpoint1 = caddy.primaryEndpoint
-export const endpoint2 = caddy.secondaryEndpoint
+if (!isMinikube) {
+  const caddy = new CaddyServiceDeployment(
+    'caddy-proxy',
+    { lbReady, namespaceName: namespaceName, isMinikube, caddyEndpoints },
+    resourceOptions
+  )
+
+  endpoint1 = pulumi.interpolate`${caddy.primaryEndpoint}`
+  endpoint2 = pulumi.interpolate`${caddy.secondaryEndpoint}`
+}

+ 0 - 16
metadata-protobuf/compile.sh

@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-
-# Directory to write generated code to (.js and .d.ts files)
-OUT_DIR="./compiled"
-mkdir -p ${OUT_DIR}
-
-yarn pbjs \
-  -t="static-module" \
-  -w="commonjs" \
-  -o="${OUT_DIR}/index.js" \
-  --force-long \
-  proto/*.proto
-
-yarn pbts \
-  -o="${OUT_DIR}/index.d.ts" \
-  ${OUT_DIR}/*.js

+ 0 - 1723
metadata-protobuf/compiled/index.d.ts

@@ -1,1723 +0,0 @@
-import { Long } from 'long'
-import * as $protobuf from "protobufjs";
-/** Properties of a ChannelMetadata. */
-export interface IChannelMetadata {
-
-    /** ChannelMetadata title */
-    title?: (string|null);
-
-    /** ChannelMetadata description */
-    description?: (string|null);
-
-    /** ChannelMetadata isPublic */
-    isPublic?: (boolean|null);
-
-    /** ChannelMetadata language */
-    language?: (string|null);
-
-    /** ChannelMetadata coverPhoto */
-    coverPhoto?: (number|null);
-
-    /** ChannelMetadata avatarPhoto */
-    avatarPhoto?: (number|null);
-
-    /** ChannelMetadata category */
-    category?: (Long|null);
-}
-
-/** Represents a ChannelMetadata. */
-export class ChannelMetadata implements IChannelMetadata {
-
-    /**
-     * Constructs a new ChannelMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IChannelMetadata);
-
-    /** ChannelMetadata title. */
-    public title: string;
-
-    /** ChannelMetadata description. */
-    public description: string;
-
-    /** ChannelMetadata isPublic. */
-    public isPublic: boolean;
-
-    /** ChannelMetadata language. */
-    public language: string;
-
-    /** ChannelMetadata coverPhoto. */
-    public coverPhoto: number;
-
-    /** ChannelMetadata avatarPhoto. */
-    public avatarPhoto: number;
-
-    /** ChannelMetadata category. */
-    public category: Long;
-
-    /**
-     * Creates a new ChannelMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns ChannelMetadata instance
-     */
-    public static create(properties?: IChannelMetadata): ChannelMetadata;
-
-    /**
-     * Encodes the specified ChannelMetadata message. Does not implicitly {@link ChannelMetadata.verify|verify} messages.
-     * @param message ChannelMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IChannelMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified ChannelMetadata message, length delimited. Does not implicitly {@link ChannelMetadata.verify|verify} messages.
-     * @param message ChannelMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IChannelMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a ChannelMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns ChannelMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): ChannelMetadata;
-
-    /**
-     * Decodes a ChannelMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns ChannelMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): ChannelMetadata;
-
-    /**
-     * Verifies a ChannelMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a ChannelMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns ChannelMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): ChannelMetadata;
-
-    /**
-     * Creates a plain object from a ChannelMetadata message. Also converts values to other types if specified.
-     * @param message ChannelMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: ChannelMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this ChannelMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a ChannelCategoryMetadata. */
-export interface IChannelCategoryMetadata {
-
-    /** ChannelCategoryMetadata name */
-    name?: (string|null);
-}
-
-/** Represents a ChannelCategoryMetadata. */
-export class ChannelCategoryMetadata implements IChannelCategoryMetadata {
-
-    /**
-     * Constructs a new ChannelCategoryMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IChannelCategoryMetadata);
-
-    /** ChannelCategoryMetadata name. */
-    public name: string;
-
-    /**
-     * Creates a new ChannelCategoryMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns ChannelCategoryMetadata instance
-     */
-    public static create(properties?: IChannelCategoryMetadata): ChannelCategoryMetadata;
-
-    /**
-     * Encodes the specified ChannelCategoryMetadata message. Does not implicitly {@link ChannelCategoryMetadata.verify|verify} messages.
-     * @param message ChannelCategoryMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IChannelCategoryMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified ChannelCategoryMetadata message, length delimited. Does not implicitly {@link ChannelCategoryMetadata.verify|verify} messages.
-     * @param message ChannelCategoryMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IChannelCategoryMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a ChannelCategoryMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns ChannelCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): ChannelCategoryMetadata;
-
-    /**
-     * Decodes a ChannelCategoryMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns ChannelCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): ChannelCategoryMetadata;
-
-    /**
-     * Verifies a ChannelCategoryMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a ChannelCategoryMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns ChannelCategoryMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): ChannelCategoryMetadata;
-
-    /**
-     * Creates a plain object from a ChannelCategoryMetadata message. Also converts values to other types if specified.
-     * @param message ChannelCategoryMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: ChannelCategoryMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this ChannelCategoryMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a PersonMetadata. */
-export interface IPersonMetadata {
-
-    /** PersonMetadata firstName */
-    firstName?: (string|null);
-
-    /** PersonMetadata middleName */
-    middleName?: (string|null);
-
-    /** PersonMetadata lastName */
-    lastName?: (string|null);
-
-    /** PersonMetadata about */
-    about?: (string|null);
-
-    /** PersonMetadata coverPhoto */
-    coverPhoto?: (number|null);
-
-    /** PersonMetadata avatarPhoto */
-    avatarPhoto?: (number|null);
-}
-
-/** Represents a PersonMetadata. */
-export class PersonMetadata implements IPersonMetadata {
-
-    /**
-     * Constructs a new PersonMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IPersonMetadata);
-
-    /** PersonMetadata firstName. */
-    public firstName: string;
-
-    /** PersonMetadata middleName. */
-    public middleName: string;
-
-    /** PersonMetadata lastName. */
-    public lastName: string;
-
-    /** PersonMetadata about. */
-    public about: string;
-
-    /** PersonMetadata coverPhoto. */
-    public coverPhoto: number;
-
-    /** PersonMetadata avatarPhoto. */
-    public avatarPhoto: number;
-
-    /**
-     * Creates a new PersonMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns PersonMetadata instance
-     */
-    public static create(properties?: IPersonMetadata): PersonMetadata;
-
-    /**
-     * Encodes the specified PersonMetadata message. Does not implicitly {@link PersonMetadata.verify|verify} messages.
-     * @param message PersonMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IPersonMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified PersonMetadata message, length delimited. Does not implicitly {@link PersonMetadata.verify|verify} messages.
-     * @param message PersonMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IPersonMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a PersonMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns PersonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): PersonMetadata;
-
-    /**
-     * Decodes a PersonMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns PersonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): PersonMetadata;
-
-    /**
-     * Verifies a PersonMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a PersonMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns PersonMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): PersonMetadata;
-
-    /**
-     * Creates a plain object from a PersonMetadata message. Also converts values to other types if specified.
-     * @param message PersonMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: PersonMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this PersonMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a PlaylistMetadata. */
-export interface IPlaylistMetadata {
-
-    /** PlaylistMetadata title */
-    title?: (string|null);
-
-    /** PlaylistMetadata videos */
-    videos?: (Long[]|null);
-}
-
-/** Represents a PlaylistMetadata. */
-export class PlaylistMetadata implements IPlaylistMetadata {
-
-    /**
-     * Constructs a new PlaylistMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IPlaylistMetadata);
-
-    /** PlaylistMetadata title. */
-    public title: string;
-
-    /** PlaylistMetadata videos. */
-    public videos: Long[];
-
-    /**
-     * Creates a new PlaylistMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns PlaylistMetadata instance
-     */
-    public static create(properties?: IPlaylistMetadata): PlaylistMetadata;
-
-    /**
-     * Encodes the specified PlaylistMetadata message. Does not implicitly {@link PlaylistMetadata.verify|verify} messages.
-     * @param message PlaylistMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IPlaylistMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified PlaylistMetadata message, length delimited. Does not implicitly {@link PlaylistMetadata.verify|verify} messages.
-     * @param message PlaylistMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IPlaylistMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a PlaylistMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns PlaylistMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): PlaylistMetadata;
-
-    /**
-     * Decodes a PlaylistMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns PlaylistMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): PlaylistMetadata;
-
-    /**
-     * Verifies a PlaylistMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a PlaylistMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns PlaylistMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): PlaylistMetadata;
-
-    /**
-     * Creates a plain object from a PlaylistMetadata message. Also converts values to other types if specified.
-     * @param message PlaylistMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: PlaylistMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this PlaylistMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a SeriesMetadata. */
-export interface ISeriesMetadata {
-
-    /** SeriesMetadata title */
-    title?: (string|null);
-
-    /** SeriesMetadata description */
-    description?: (string|null);
-
-    /** SeriesMetadata coverPhoto */
-    coverPhoto?: (number|null);
-
-    /** SeriesMetadata persons */
-    persons?: (Long[]|null);
-}
-
-/** Represents a SeriesMetadata. */
-export class SeriesMetadata implements ISeriesMetadata {
-
-    /**
-     * Constructs a new SeriesMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: ISeriesMetadata);
-
-    /** SeriesMetadata title. */
-    public title: string;
-
-    /** SeriesMetadata description. */
-    public description: string;
-
-    /** SeriesMetadata coverPhoto. */
-    public coverPhoto: number;
-
-    /** SeriesMetadata persons. */
-    public persons: Long[];
-
-    /**
-     * Creates a new SeriesMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns SeriesMetadata instance
-     */
-    public static create(properties?: ISeriesMetadata): SeriesMetadata;
-
-    /**
-     * Encodes the specified SeriesMetadata message. Does not implicitly {@link SeriesMetadata.verify|verify} messages.
-     * @param message SeriesMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: ISeriesMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified SeriesMetadata message, length delimited. Does not implicitly {@link SeriesMetadata.verify|verify} messages.
-     * @param message SeriesMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: ISeriesMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a SeriesMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns SeriesMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SeriesMetadata;
-
-    /**
-     * Decodes a SeriesMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns SeriesMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SeriesMetadata;
-
-    /**
-     * Verifies a SeriesMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a SeriesMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns SeriesMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): SeriesMetadata;
-
-    /**
-     * Creates a plain object from a SeriesMetadata message. Also converts values to other types if specified.
-     * @param message SeriesMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: SeriesMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this SeriesMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a SeasonMetadata. */
-export interface ISeasonMetadata {
-
-    /** SeasonMetadata title */
-    title?: (string|null);
-
-    /** SeasonMetadata description */
-    description?: (string|null);
-
-    /** SeasonMetadata coverPhoto */
-    coverPhoto?: (number|null);
-
-    /** SeasonMetadata persons */
-    persons?: (Long[]|null);
-}
-
-/** Represents a SeasonMetadata. */
-export class SeasonMetadata implements ISeasonMetadata {
-
-    /**
-     * Constructs a new SeasonMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: ISeasonMetadata);
-
-    /** SeasonMetadata title. */
-    public title: string;
-
-    /** SeasonMetadata description. */
-    public description: string;
-
-    /** SeasonMetadata coverPhoto. */
-    public coverPhoto: number;
-
-    /** SeasonMetadata persons. */
-    public persons: Long[];
-
-    /**
-     * Creates a new SeasonMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns SeasonMetadata instance
-     */
-    public static create(properties?: ISeasonMetadata): SeasonMetadata;
-
-    /**
-     * Encodes the specified SeasonMetadata message. Does not implicitly {@link SeasonMetadata.verify|verify} messages.
-     * @param message SeasonMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: ISeasonMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified SeasonMetadata message, length delimited. Does not implicitly {@link SeasonMetadata.verify|verify} messages.
-     * @param message SeasonMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: ISeasonMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a SeasonMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns SeasonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SeasonMetadata;
-
-    /**
-     * Decodes a SeasonMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns SeasonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SeasonMetadata;
-
-    /**
-     * Verifies a SeasonMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a SeasonMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns SeasonMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): SeasonMetadata;
-
-    /**
-     * Creates a plain object from a SeasonMetadata message. Also converts values to other types if specified.
-     * @param message SeasonMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: SeasonMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this SeasonMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a GeoCoordiantes. */
-export interface IGeoCoordiantes {
-
-    /** GeoCoordiantes latitude */
-    latitude?: (number|null);
-
-    /** GeoCoordiantes longitude */
-    longitude?: (number|null);
-}
-
-/** Represents a GeoCoordiantes. */
-export class GeoCoordiantes implements IGeoCoordiantes {
-
-    /**
-     * Constructs a new GeoCoordiantes.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IGeoCoordiantes);
-
-    /** GeoCoordiantes latitude. */
-    public latitude: number;
-
-    /** GeoCoordiantes longitude. */
-    public longitude: number;
-
-    /**
-     * Creates a new GeoCoordiantes instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns GeoCoordiantes instance
-     */
-    public static create(properties?: IGeoCoordiantes): GeoCoordiantes;
-
-    /**
-     * Encodes the specified GeoCoordiantes message. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @param message GeoCoordiantes message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IGeoCoordiantes, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified GeoCoordiantes message, length delimited. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @param message GeoCoordiantes message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IGeoCoordiantes, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): GeoCoordiantes;
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): GeoCoordiantes;
-
-    /**
-     * Verifies a GeoCoordiantes message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a GeoCoordiantes message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns GeoCoordiantes
-     */
-    public static fromObject(object: { [k: string]: any }): GeoCoordiantes;
-
-    /**
-     * Creates a plain object from a GeoCoordiantes message. Also converts values to other types if specified.
-     * @param message GeoCoordiantes
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: GeoCoordiantes, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this GeoCoordiantes to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a NodeLocationMetadata. */
-export interface INodeLocationMetadata {
-
-    /** NodeLocationMetadata countryCode */
-    countryCode?: (string|null);
-
-    /** NodeLocationMetadata city */
-    city?: (string|null);
-
-    /** NodeLocationMetadata coordinates */
-    coordinates?: (IGeoCoordiantes|null);
-}
-
-/** Represents a NodeLocationMetadata. */
-export class NodeLocationMetadata implements INodeLocationMetadata {
-
-    /**
-     * Constructs a new NodeLocationMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: INodeLocationMetadata);
-
-    /** NodeLocationMetadata countryCode. */
-    public countryCode: string;
-
-    /** NodeLocationMetadata city. */
-    public city: string;
-
-    /** NodeLocationMetadata coordinates. */
-    public coordinates?: (IGeoCoordiantes|null);
-
-    /**
-     * Creates a new NodeLocationMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns NodeLocationMetadata instance
-     */
-    public static create(properties?: INodeLocationMetadata): NodeLocationMetadata;
-
-    /**
-     * Encodes the specified NodeLocationMetadata message. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @param message NodeLocationMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: INodeLocationMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified NodeLocationMetadata message, length delimited. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @param message NodeLocationMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: INodeLocationMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): NodeLocationMetadata;
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): NodeLocationMetadata;
-
-    /**
-     * Verifies a NodeLocationMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a NodeLocationMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns NodeLocationMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): NodeLocationMetadata;
-
-    /**
-     * Creates a plain object from a NodeLocationMetadata message. Also converts values to other types if specified.
-     * @param message NodeLocationMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: NodeLocationMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this NodeLocationMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a StorageBucketOperatorMetadata. */
-export interface IStorageBucketOperatorMetadata {
-
-    /** StorageBucketOperatorMetadata endpoint */
-    endpoint?: (string|null);
-
-    /** StorageBucketOperatorMetadata location */
-    location?: (INodeLocationMetadata|null);
-
-    /** StorageBucketOperatorMetadata extra */
-    extra?: (string|null);
-}
-
-/** Represents a StorageBucketOperatorMetadata. */
-export class StorageBucketOperatorMetadata implements IStorageBucketOperatorMetadata {
-
-    /**
-     * Constructs a new StorageBucketOperatorMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IStorageBucketOperatorMetadata);
-
-    /** StorageBucketOperatorMetadata endpoint. */
-    public endpoint: string;
-
-    /** StorageBucketOperatorMetadata location. */
-    public location?: (INodeLocationMetadata|null);
-
-    /** StorageBucketOperatorMetadata extra. */
-    public extra: string;
-
-    /**
-     * Creates a new StorageBucketOperatorMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns StorageBucketOperatorMetadata instance
-     */
-    public static create(properties?: IStorageBucketOperatorMetadata): StorageBucketOperatorMetadata;
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @param message StorageBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IStorageBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message, length delimited. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @param message StorageBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IStorageBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): StorageBucketOperatorMetadata;
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): StorageBucketOperatorMetadata;
-
-    /**
-     * Verifies a StorageBucketOperatorMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a StorageBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns StorageBucketOperatorMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): StorageBucketOperatorMetadata;
-
-    /**
-     * Creates a plain object from a StorageBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @param message StorageBucketOperatorMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: StorageBucketOperatorMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this StorageBucketOperatorMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a DistributionBucketOperatorMetadata. */
-export interface IDistributionBucketOperatorMetadata {
-
-    /** DistributionBucketOperatorMetadata endpoint */
-    endpoint?: (string|null);
-
-    /** DistributionBucketOperatorMetadata location */
-    location?: (INodeLocationMetadata|null);
-
-    /** DistributionBucketOperatorMetadata extra */
-    extra?: (string|null);
-}
-
-/** Represents a DistributionBucketOperatorMetadata. */
-export class DistributionBucketOperatorMetadata implements IDistributionBucketOperatorMetadata {
-
-    /**
-     * Constructs a new DistributionBucketOperatorMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IDistributionBucketOperatorMetadata);
-
-    /** DistributionBucketOperatorMetadata endpoint. */
-    public endpoint: string;
-
-    /** DistributionBucketOperatorMetadata location. */
-    public location?: (INodeLocationMetadata|null);
-
-    /** DistributionBucketOperatorMetadata extra. */
-    public extra: string;
-
-    /**
-     * Creates a new DistributionBucketOperatorMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns DistributionBucketOperatorMetadata instance
-     */
-    public static create(properties?: IDistributionBucketOperatorMetadata): DistributionBucketOperatorMetadata;
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @param message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IDistributionBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message, length delimited. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @param message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IDistributionBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): DistributionBucketOperatorMetadata;
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): DistributionBucketOperatorMetadata;
-
-    /**
-     * Verifies a DistributionBucketOperatorMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a DistributionBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns DistributionBucketOperatorMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): DistributionBucketOperatorMetadata;
-
-    /**
-     * Creates a plain object from a DistributionBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @param message DistributionBucketOperatorMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: DistributionBucketOperatorMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this DistributionBucketOperatorMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a DistributionBucketFamilyMetadata. */
-export interface IDistributionBucketFamilyMetadata {
-
-    /** DistributionBucketFamilyMetadata region */
-    region?: (string|null);
-
-    /** DistributionBucketFamilyMetadata description */
-    description?: (string|null);
-
-    /** DistributionBucketFamilyMetadata boundary */
-    boundary?: (IGeoCoordiantes[]|null);
-}
-
-/** Represents a DistributionBucketFamilyMetadata. */
-export class DistributionBucketFamilyMetadata implements IDistributionBucketFamilyMetadata {
-
-    /**
-     * Constructs a new DistributionBucketFamilyMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IDistributionBucketFamilyMetadata);
-
-    /** DistributionBucketFamilyMetadata region. */
-    public region: string;
-
-    /** DistributionBucketFamilyMetadata description. */
-    public description: string;
-
-    /** DistributionBucketFamilyMetadata boundary. */
-    public boundary: IGeoCoordiantes[];
-
-    /**
-     * Creates a new DistributionBucketFamilyMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns DistributionBucketFamilyMetadata instance
-     */
-    public static create(properties?: IDistributionBucketFamilyMetadata): DistributionBucketFamilyMetadata;
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @param message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IDistributionBucketFamilyMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message, length delimited. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @param message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IDistributionBucketFamilyMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): DistributionBucketFamilyMetadata;
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): DistributionBucketFamilyMetadata;
-
-    /**
-     * Verifies a DistributionBucketFamilyMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a DistributionBucketFamilyMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns DistributionBucketFamilyMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): DistributionBucketFamilyMetadata;
-
-    /**
-     * Creates a plain object from a DistributionBucketFamilyMetadata message. Also converts values to other types if specified.
-     * @param message DistributionBucketFamilyMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: DistributionBucketFamilyMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this DistributionBucketFamilyMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a PublishedBeforeJoystream. */
-export interface IPublishedBeforeJoystream {
-
-    /** PublishedBeforeJoystream isPublished */
-    isPublished?: (boolean|null);
-
-    /** PublishedBeforeJoystream date */
-    date?: (string|null);
-}
-
-/** Represents a PublishedBeforeJoystream. */
-export class PublishedBeforeJoystream implements IPublishedBeforeJoystream {
-
-    /**
-     * Constructs a new PublishedBeforeJoystream.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IPublishedBeforeJoystream);
-
-    /** PublishedBeforeJoystream isPublished. */
-    public isPublished: boolean;
-
-    /** PublishedBeforeJoystream date. */
-    public date: string;
-
-    /**
-     * Creates a new PublishedBeforeJoystream instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns PublishedBeforeJoystream instance
-     */
-    public static create(properties?: IPublishedBeforeJoystream): PublishedBeforeJoystream;
-
-    /**
-     * Encodes the specified PublishedBeforeJoystream message. Does not implicitly {@link PublishedBeforeJoystream.verify|verify} messages.
-     * @param message PublishedBeforeJoystream message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IPublishedBeforeJoystream, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified PublishedBeforeJoystream message, length delimited. Does not implicitly {@link PublishedBeforeJoystream.verify|verify} messages.
-     * @param message PublishedBeforeJoystream message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IPublishedBeforeJoystream, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a PublishedBeforeJoystream message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns PublishedBeforeJoystream
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): PublishedBeforeJoystream;
-
-    /**
-     * Decodes a PublishedBeforeJoystream message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns PublishedBeforeJoystream
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): PublishedBeforeJoystream;
-
-    /**
-     * Verifies a PublishedBeforeJoystream message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a PublishedBeforeJoystream message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns PublishedBeforeJoystream
-     */
-    public static fromObject(object: { [k: string]: any }): PublishedBeforeJoystream;
-
-    /**
-     * Creates a plain object from a PublishedBeforeJoystream message. Also converts values to other types if specified.
-     * @param message PublishedBeforeJoystream
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: PublishedBeforeJoystream, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this PublishedBeforeJoystream to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a License. */
-export interface ILicense {
-
-    /** License code */
-    code?: (number|null);
-
-    /** License attribution */
-    attribution?: (string|null);
-
-    /** License customText */
-    customText?: (string|null);
-}
-
-/** Represents a License. */
-export class License implements ILicense {
-
-    /**
-     * Constructs a new License.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: ILicense);
-
-    /** License code. */
-    public code: number;
-
-    /** License attribution. */
-    public attribution: string;
-
-    /** License customText. */
-    public customText: string;
-
-    /**
-     * Creates a new License instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns License instance
-     */
-    public static create(properties?: ILicense): License;
-
-    /**
-     * Encodes the specified License message. Does not implicitly {@link License.verify|verify} messages.
-     * @param message License message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: ILicense, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified License message, length delimited. Does not implicitly {@link License.verify|verify} messages.
-     * @param message License message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: ILicense, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a License message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns License
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): License;
-
-    /**
-     * Decodes a License message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns License
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): License;
-
-    /**
-     * Verifies a License message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a License message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns License
-     */
-    public static fromObject(object: { [k: string]: any }): License;
-
-    /**
-     * Creates a plain object from a License message. Also converts values to other types if specified.
-     * @param message License
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: License, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this License to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a MediaType. */
-export interface IMediaType {
-
-    /** MediaType codecName */
-    codecName?: (string|null);
-
-    /** MediaType container */
-    container?: (string|null);
-
-    /** MediaType mimeMediaType */
-    mimeMediaType?: (string|null);
-}
-
-/** Represents a MediaType. */
-export class MediaType implements IMediaType {
-
-    /**
-     * Constructs a new MediaType.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IMediaType);
-
-    /** MediaType codecName. */
-    public codecName: string;
-
-    /** MediaType container. */
-    public container: string;
-
-    /** MediaType mimeMediaType. */
-    public mimeMediaType: string;
-
-    /**
-     * Creates a new MediaType instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns MediaType instance
-     */
-    public static create(properties?: IMediaType): MediaType;
-
-    /**
-     * Encodes the specified MediaType message. Does not implicitly {@link MediaType.verify|verify} messages.
-     * @param message MediaType message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IMediaType, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified MediaType message, length delimited. Does not implicitly {@link MediaType.verify|verify} messages.
-     * @param message MediaType message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IMediaType, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a MediaType message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns MediaType
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): MediaType;
-
-    /**
-     * Decodes a MediaType message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns MediaType
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): MediaType;
-
-    /**
-     * Verifies a MediaType message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a MediaType message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns MediaType
-     */
-    public static fromObject(object: { [k: string]: any }): MediaType;
-
-    /**
-     * Creates a plain object from a MediaType message. Also converts values to other types if specified.
-     * @param message MediaType
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: MediaType, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this MediaType to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a VideoMetadata. */
-export interface IVideoMetadata {
-
-    /** VideoMetadata title */
-    title?: (string|null);
-
-    /** VideoMetadata description */
-    description?: (string|null);
-
-    /** VideoMetadata video */
-    video?: (number|null);
-
-    /** VideoMetadata thumbnailPhoto */
-    thumbnailPhoto?: (number|null);
-
-    /** VideoMetadata duration */
-    duration?: (number|null);
-
-    /** VideoMetadata mediaPixelHeight */
-    mediaPixelHeight?: (number|null);
-
-    /** VideoMetadata mediaPixelWidth */
-    mediaPixelWidth?: (number|null);
-
-    /** VideoMetadata mediaType */
-    mediaType?: (IMediaType|null);
-
-    /** VideoMetadata language */
-    language?: (string|null);
-
-    /** VideoMetadata license */
-    license?: (ILicense|null);
-
-    /** VideoMetadata publishedBeforeJoystream */
-    publishedBeforeJoystream?: (IPublishedBeforeJoystream|null);
-
-    /** VideoMetadata hasMarketing */
-    hasMarketing?: (boolean|null);
-
-    /** VideoMetadata isPublic */
-    isPublic?: (boolean|null);
-
-    /** VideoMetadata isExplicit */
-    isExplicit?: (boolean|null);
-
-    /** VideoMetadata persons */
-    persons?: (Long[]|null);
-
-    /** VideoMetadata category */
-    category?: (Long|null);
-}
-
-/** Represents a VideoMetadata. */
-export class VideoMetadata implements IVideoMetadata {
-
-    /**
-     * Constructs a new VideoMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IVideoMetadata);
-
-    /** VideoMetadata title. */
-    public title: string;
-
-    /** VideoMetadata description. */
-    public description: string;
-
-    /** VideoMetadata video. */
-    public video: number;
-
-    /** VideoMetadata thumbnailPhoto. */
-    public thumbnailPhoto: number;
-
-    /** VideoMetadata duration. */
-    public duration: number;
-
-    /** VideoMetadata mediaPixelHeight. */
-    public mediaPixelHeight: number;
-
-    /** VideoMetadata mediaPixelWidth. */
-    public mediaPixelWidth: number;
-
-    /** VideoMetadata mediaType. */
-    public mediaType?: (IMediaType|null);
-
-    /** VideoMetadata language. */
-    public language: string;
-
-    /** VideoMetadata license. */
-    public license?: (ILicense|null);
-
-    /** VideoMetadata publishedBeforeJoystream. */
-    public publishedBeforeJoystream?: (IPublishedBeforeJoystream|null);
-
-    /** VideoMetadata hasMarketing. */
-    public hasMarketing: boolean;
-
-    /** VideoMetadata isPublic. */
-    public isPublic: boolean;
-
-    /** VideoMetadata isExplicit. */
-    public isExplicit: boolean;
-
-    /** VideoMetadata persons. */
-    public persons: Long[];
-
-    /** VideoMetadata category. */
-    public category: Long;
-
-    /**
-     * Creates a new VideoMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns VideoMetadata instance
-     */
-    public static create(properties?: IVideoMetadata): VideoMetadata;
-
-    /**
-     * Encodes the specified VideoMetadata message. Does not implicitly {@link VideoMetadata.verify|verify} messages.
-     * @param message VideoMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IVideoMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified VideoMetadata message, length delimited. Does not implicitly {@link VideoMetadata.verify|verify} messages.
-     * @param message VideoMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IVideoMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a VideoMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns VideoMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): VideoMetadata;
-
-    /**
-     * Decodes a VideoMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns VideoMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): VideoMetadata;
-
-    /**
-     * Verifies a VideoMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a VideoMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns VideoMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): VideoMetadata;
-
-    /**
-     * Creates a plain object from a VideoMetadata message. Also converts values to other types if specified.
-     * @param message VideoMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: VideoMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this VideoMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a VideoCategoryMetadata. */
-export interface IVideoCategoryMetadata {
-
-    /** VideoCategoryMetadata name */
-    name?: (string|null);
-}
-
-/** Represents a VideoCategoryMetadata. */
-export class VideoCategoryMetadata implements IVideoCategoryMetadata {
-
-    /**
-     * Constructs a new VideoCategoryMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IVideoCategoryMetadata);
-
-    /** VideoCategoryMetadata name. */
-    public name: string;
-
-    /**
-     * Creates a new VideoCategoryMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns VideoCategoryMetadata instance
-     */
-    public static create(properties?: IVideoCategoryMetadata): VideoCategoryMetadata;
-
-    /**
-     * Encodes the specified VideoCategoryMetadata message. Does not implicitly {@link VideoCategoryMetadata.verify|verify} messages.
-     * @param message VideoCategoryMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IVideoCategoryMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified VideoCategoryMetadata message, length delimited. Does not implicitly {@link VideoCategoryMetadata.verify|verify} messages.
-     * @param message VideoCategoryMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IVideoCategoryMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a VideoCategoryMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns VideoCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): VideoCategoryMetadata;
-
-    /**
-     * Decodes a VideoCategoryMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns VideoCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): VideoCategoryMetadata;
-
-    /**
-     * Verifies a VideoCategoryMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a VideoCategoryMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns VideoCategoryMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): VideoCategoryMetadata;
-
-    /**
-     * Creates a plain object from a VideoCategoryMetadata message. Also converts values to other types if specified.
-     * @param message VideoCategoryMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: VideoCategoryMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this VideoCategoryMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}

+ 0 - 4268
metadata-protobuf/compiled/index.js

@@ -1,4268 +0,0 @@
-/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
-"use strict";
-
-var $protobuf = require("protobufjs/minimal");
-
-// Common aliases
-var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
-
-// Exported root namespace
-var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});
-
-$root.ChannelMetadata = (function() {
-
-    /**
-     * Properties of a ChannelMetadata.
-     * @exports IChannelMetadata
-     * @interface IChannelMetadata
-     * @property {string|null} [title] ChannelMetadata title
-     * @property {string|null} [description] ChannelMetadata description
-     * @property {boolean|null} [isPublic] ChannelMetadata isPublic
-     * @property {string|null} [language] ChannelMetadata language
-     * @property {number|null} [coverPhoto] ChannelMetadata coverPhoto
-     * @property {number|null} [avatarPhoto] ChannelMetadata avatarPhoto
-     * @property {Long|null} [category] ChannelMetadata category
-     */
-
-    /**
-     * Constructs a new ChannelMetadata.
-     * @exports ChannelMetadata
-     * @classdesc Represents a ChannelMetadata.
-     * @implements IChannelMetadata
-     * @constructor
-     * @param {IChannelMetadata=} [properties] Properties to set
-     */
-    function ChannelMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * ChannelMetadata title.
-     * @member {string} title
-     * @memberof ChannelMetadata
-     * @instance
-     */
-    ChannelMetadata.prototype.title = "";
-
-    /**
-     * ChannelMetadata description.
-     * @member {string} description
-     * @memberof ChannelMetadata
-     * @instance
-     */
-    ChannelMetadata.prototype.description = "";
-
-    /**
-     * ChannelMetadata isPublic.
-     * @member {boolean} isPublic
-     * @memberof ChannelMetadata
-     * @instance
-     */
-    ChannelMetadata.prototype.isPublic = false;
-
-    /**
-     * ChannelMetadata language.
-     * @member {string} language
-     * @memberof ChannelMetadata
-     * @instance
-     */
-    ChannelMetadata.prototype.language = "";
-
-    /**
-     * ChannelMetadata coverPhoto.
-     * @member {number} coverPhoto
-     * @memberof ChannelMetadata
-     * @instance
-     */
-    ChannelMetadata.prototype.coverPhoto = 0;
-
-    /**
-     * ChannelMetadata avatarPhoto.
-     * @member {number} avatarPhoto
-     * @memberof ChannelMetadata
-     * @instance
-     */
-    ChannelMetadata.prototype.avatarPhoto = 0;
-
-    /**
-     * ChannelMetadata category.
-     * @member {Long} category
-     * @memberof ChannelMetadata
-     * @instance
-     */
-    ChannelMetadata.prototype.category = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
-
-    /**
-     * Creates a new ChannelMetadata instance using the specified properties.
-     * @function create
-     * @memberof ChannelMetadata
-     * @static
-     * @param {IChannelMetadata=} [properties] Properties to set
-     * @returns {ChannelMetadata} ChannelMetadata instance
-     */
-    ChannelMetadata.create = function create(properties) {
-        return new ChannelMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified ChannelMetadata message. Does not implicitly {@link ChannelMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof ChannelMetadata
-     * @static
-     * @param {IChannelMetadata} message ChannelMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    ChannelMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.title != null && Object.hasOwnProperty.call(message, "title"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
-        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
-        if (message.isPublic != null && Object.hasOwnProperty.call(message, "isPublic"))
-            writer.uint32(/* id 3, wireType 0 =*/24).bool(message.isPublic);
-        if (message.language != null && Object.hasOwnProperty.call(message, "language"))
-            writer.uint32(/* id 4, wireType 2 =*/34).string(message.language);
-        if (message.coverPhoto != null && Object.hasOwnProperty.call(message, "coverPhoto"))
-            writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.coverPhoto);
-        if (message.avatarPhoto != null && Object.hasOwnProperty.call(message, "avatarPhoto"))
-            writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.avatarPhoto);
-        if (message.category != null && Object.hasOwnProperty.call(message, "category"))
-            writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.category);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified ChannelMetadata message, length delimited. Does not implicitly {@link ChannelMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof ChannelMetadata
-     * @static
-     * @param {IChannelMetadata} message ChannelMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    ChannelMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a ChannelMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof ChannelMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {ChannelMetadata} ChannelMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    ChannelMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.ChannelMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.title = reader.string();
-                break;
-            case 2:
-                message.description = reader.string();
-                break;
-            case 3:
-                message.isPublic = reader.bool();
-                break;
-            case 4:
-                message.language = reader.string();
-                break;
-            case 5:
-                message.coverPhoto = reader.uint32();
-                break;
-            case 6:
-                message.avatarPhoto = reader.uint32();
-                break;
-            case 7:
-                message.category = reader.uint64();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a ChannelMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof ChannelMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {ChannelMetadata} ChannelMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    ChannelMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a ChannelMetadata message.
-     * @function verify
-     * @memberof ChannelMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    ChannelMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.title != null && message.hasOwnProperty("title"))
-            if (!$util.isString(message.title))
-                return "title: string expected";
-        if (message.description != null && message.hasOwnProperty("description"))
-            if (!$util.isString(message.description))
-                return "description: string expected";
-        if (message.isPublic != null && message.hasOwnProperty("isPublic"))
-            if (typeof message.isPublic !== "boolean")
-                return "isPublic: boolean expected";
-        if (message.language != null && message.hasOwnProperty("language"))
-            if (!$util.isString(message.language))
-                return "language: string expected";
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            if (!$util.isInteger(message.coverPhoto))
-                return "coverPhoto: integer expected";
-        if (message.avatarPhoto != null && message.hasOwnProperty("avatarPhoto"))
-            if (!$util.isInteger(message.avatarPhoto))
-                return "avatarPhoto: integer expected";
-        if (message.category != null && message.hasOwnProperty("category"))
-            if (!$util.isInteger(message.category) && !(message.category && $util.isInteger(message.category.low) && $util.isInteger(message.category.high)))
-                return "category: integer|Long expected";
-        return null;
-    };
-
-    /**
-     * Creates a ChannelMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof ChannelMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {ChannelMetadata} ChannelMetadata
-     */
-    ChannelMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.ChannelMetadata)
-            return object;
-        var message = new $root.ChannelMetadata();
-        if (object.title != null)
-            message.title = String(object.title);
-        if (object.description != null)
-            message.description = String(object.description);
-        if (object.isPublic != null)
-            message.isPublic = Boolean(object.isPublic);
-        if (object.language != null)
-            message.language = String(object.language);
-        if (object.coverPhoto != null)
-            message.coverPhoto = object.coverPhoto >>> 0;
-        if (object.avatarPhoto != null)
-            message.avatarPhoto = object.avatarPhoto >>> 0;
-        if (object.category != null)
-            if ($util.Long)
-                (message.category = $util.Long.fromValue(object.category)).unsigned = true;
-            else if (typeof object.category === "string")
-                message.category = parseInt(object.category, 10);
-            else if (typeof object.category === "number")
-                message.category = object.category;
-            else if (typeof object.category === "object")
-                message.category = new $util.LongBits(object.category.low >>> 0, object.category.high >>> 0).toNumber(true);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a ChannelMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof ChannelMetadata
-     * @static
-     * @param {ChannelMetadata} message ChannelMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    ChannelMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.title = "";
-            object.description = "";
-            object.isPublic = false;
-            object.language = "";
-            object.coverPhoto = 0;
-            object.avatarPhoto = 0;
-            if ($util.Long) {
-                var long = new $util.Long(0, 0, true);
-                object.category = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
-            } else
-                object.category = options.longs === String ? "0" : 0;
-        }
-        if (message.title != null && message.hasOwnProperty("title"))
-            object.title = message.title;
-        if (message.description != null && message.hasOwnProperty("description"))
-            object.description = message.description;
-        if (message.isPublic != null && message.hasOwnProperty("isPublic"))
-            object.isPublic = message.isPublic;
-        if (message.language != null && message.hasOwnProperty("language"))
-            object.language = message.language;
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            object.coverPhoto = message.coverPhoto;
-        if (message.avatarPhoto != null && message.hasOwnProperty("avatarPhoto"))
-            object.avatarPhoto = message.avatarPhoto;
-        if (message.category != null && message.hasOwnProperty("category"))
-            if (typeof message.category === "number")
-                object.category = options.longs === String ? String(message.category) : message.category;
-            else
-                object.category = options.longs === String ? $util.Long.prototype.toString.call(message.category) : options.longs === Number ? new $util.LongBits(message.category.low >>> 0, message.category.high >>> 0).toNumber(true) : message.category;
-        return object;
-    };
-
-    /**
-     * Converts this ChannelMetadata to JSON.
-     * @function toJSON
-     * @memberof ChannelMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    ChannelMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return ChannelMetadata;
-})();
-
-$root.ChannelCategoryMetadata = (function() {
-
-    /**
-     * Properties of a ChannelCategoryMetadata.
-     * @exports IChannelCategoryMetadata
-     * @interface IChannelCategoryMetadata
-     * @property {string|null} [name] ChannelCategoryMetadata name
-     */
-
-    /**
-     * Constructs a new ChannelCategoryMetadata.
-     * @exports ChannelCategoryMetadata
-     * @classdesc Represents a ChannelCategoryMetadata.
-     * @implements IChannelCategoryMetadata
-     * @constructor
-     * @param {IChannelCategoryMetadata=} [properties] Properties to set
-     */
-    function ChannelCategoryMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * ChannelCategoryMetadata name.
-     * @member {string} name
-     * @memberof ChannelCategoryMetadata
-     * @instance
-     */
-    ChannelCategoryMetadata.prototype.name = "";
-
-    /**
-     * Creates a new ChannelCategoryMetadata instance using the specified properties.
-     * @function create
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {IChannelCategoryMetadata=} [properties] Properties to set
-     * @returns {ChannelCategoryMetadata} ChannelCategoryMetadata instance
-     */
-    ChannelCategoryMetadata.create = function create(properties) {
-        return new ChannelCategoryMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified ChannelCategoryMetadata message. Does not implicitly {@link ChannelCategoryMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {IChannelCategoryMetadata} message ChannelCategoryMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    ChannelCategoryMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.name != null && Object.hasOwnProperty.call(message, "name"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified ChannelCategoryMetadata message, length delimited. Does not implicitly {@link ChannelCategoryMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {IChannelCategoryMetadata} message ChannelCategoryMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    ChannelCategoryMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a ChannelCategoryMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {ChannelCategoryMetadata} ChannelCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    ChannelCategoryMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.ChannelCategoryMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.name = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a ChannelCategoryMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {ChannelCategoryMetadata} ChannelCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    ChannelCategoryMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a ChannelCategoryMetadata message.
-     * @function verify
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    ChannelCategoryMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.name != null && message.hasOwnProperty("name"))
-            if (!$util.isString(message.name))
-                return "name: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a ChannelCategoryMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {ChannelCategoryMetadata} ChannelCategoryMetadata
-     */
-    ChannelCategoryMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.ChannelCategoryMetadata)
-            return object;
-        var message = new $root.ChannelCategoryMetadata();
-        if (object.name != null)
-            message.name = String(object.name);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a ChannelCategoryMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof ChannelCategoryMetadata
-     * @static
-     * @param {ChannelCategoryMetadata} message ChannelCategoryMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    ChannelCategoryMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults)
-            object.name = "";
-        if (message.name != null && message.hasOwnProperty("name"))
-            object.name = message.name;
-        return object;
-    };
-
-    /**
-     * Converts this ChannelCategoryMetadata to JSON.
-     * @function toJSON
-     * @memberof ChannelCategoryMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    ChannelCategoryMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return ChannelCategoryMetadata;
-})();
-
-$root.PersonMetadata = (function() {
-
-    /**
-     * Properties of a PersonMetadata.
-     * @exports IPersonMetadata
-     * @interface IPersonMetadata
-     * @property {string|null} [firstName] PersonMetadata firstName
-     * @property {string|null} [middleName] PersonMetadata middleName
-     * @property {string|null} [lastName] PersonMetadata lastName
-     * @property {string|null} [about] PersonMetadata about
-     * @property {number|null} [coverPhoto] PersonMetadata coverPhoto
-     * @property {number|null} [avatarPhoto] PersonMetadata avatarPhoto
-     */
-
-    /**
-     * Constructs a new PersonMetadata.
-     * @exports PersonMetadata
-     * @classdesc Represents a PersonMetadata.
-     * @implements IPersonMetadata
-     * @constructor
-     * @param {IPersonMetadata=} [properties] Properties to set
-     */
-    function PersonMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * PersonMetadata firstName.
-     * @member {string} firstName
-     * @memberof PersonMetadata
-     * @instance
-     */
-    PersonMetadata.prototype.firstName = "";
-
-    /**
-     * PersonMetadata middleName.
-     * @member {string} middleName
-     * @memberof PersonMetadata
-     * @instance
-     */
-    PersonMetadata.prototype.middleName = "";
-
-    /**
-     * PersonMetadata lastName.
-     * @member {string} lastName
-     * @memberof PersonMetadata
-     * @instance
-     */
-    PersonMetadata.prototype.lastName = "";
-
-    /**
-     * PersonMetadata about.
-     * @member {string} about
-     * @memberof PersonMetadata
-     * @instance
-     */
-    PersonMetadata.prototype.about = "";
-
-    /**
-     * PersonMetadata coverPhoto.
-     * @member {number} coverPhoto
-     * @memberof PersonMetadata
-     * @instance
-     */
-    PersonMetadata.prototype.coverPhoto = 0;
-
-    /**
-     * PersonMetadata avatarPhoto.
-     * @member {number} avatarPhoto
-     * @memberof PersonMetadata
-     * @instance
-     */
-    PersonMetadata.prototype.avatarPhoto = 0;
-
-    /**
-     * Creates a new PersonMetadata instance using the specified properties.
-     * @function create
-     * @memberof PersonMetadata
-     * @static
-     * @param {IPersonMetadata=} [properties] Properties to set
-     * @returns {PersonMetadata} PersonMetadata instance
-     */
-    PersonMetadata.create = function create(properties) {
-        return new PersonMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified PersonMetadata message. Does not implicitly {@link PersonMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof PersonMetadata
-     * @static
-     * @param {IPersonMetadata} message PersonMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    PersonMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.firstName != null && Object.hasOwnProperty.call(message, "firstName"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.firstName);
-        if (message.middleName != null && Object.hasOwnProperty.call(message, "middleName"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.middleName);
-        if (message.lastName != null && Object.hasOwnProperty.call(message, "lastName"))
-            writer.uint32(/* id 3, wireType 2 =*/26).string(message.lastName);
-        if (message.about != null && Object.hasOwnProperty.call(message, "about"))
-            writer.uint32(/* id 4, wireType 2 =*/34).string(message.about);
-        if (message.coverPhoto != null && Object.hasOwnProperty.call(message, "coverPhoto"))
-            writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.coverPhoto);
-        if (message.avatarPhoto != null && Object.hasOwnProperty.call(message, "avatarPhoto"))
-            writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.avatarPhoto);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified PersonMetadata message, length delimited. Does not implicitly {@link PersonMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof PersonMetadata
-     * @static
-     * @param {IPersonMetadata} message PersonMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    PersonMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a PersonMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof PersonMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {PersonMetadata} PersonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    PersonMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.PersonMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.firstName = reader.string();
-                break;
-            case 2:
-                message.middleName = reader.string();
-                break;
-            case 3:
-                message.lastName = reader.string();
-                break;
-            case 4:
-                message.about = reader.string();
-                break;
-            case 5:
-                message.coverPhoto = reader.uint32();
-                break;
-            case 6:
-                message.avatarPhoto = reader.uint32();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a PersonMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof PersonMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {PersonMetadata} PersonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    PersonMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a PersonMetadata message.
-     * @function verify
-     * @memberof PersonMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    PersonMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.firstName != null && message.hasOwnProperty("firstName"))
-            if (!$util.isString(message.firstName))
-                return "firstName: string expected";
-        if (message.middleName != null && message.hasOwnProperty("middleName"))
-            if (!$util.isString(message.middleName))
-                return "middleName: string expected";
-        if (message.lastName != null && message.hasOwnProperty("lastName"))
-            if (!$util.isString(message.lastName))
-                return "lastName: string expected";
-        if (message.about != null && message.hasOwnProperty("about"))
-            if (!$util.isString(message.about))
-                return "about: string expected";
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            if (!$util.isInteger(message.coverPhoto))
-                return "coverPhoto: integer expected";
-        if (message.avatarPhoto != null && message.hasOwnProperty("avatarPhoto"))
-            if (!$util.isInteger(message.avatarPhoto))
-                return "avatarPhoto: integer expected";
-        return null;
-    };
-
-    /**
-     * Creates a PersonMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof PersonMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {PersonMetadata} PersonMetadata
-     */
-    PersonMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.PersonMetadata)
-            return object;
-        var message = new $root.PersonMetadata();
-        if (object.firstName != null)
-            message.firstName = String(object.firstName);
-        if (object.middleName != null)
-            message.middleName = String(object.middleName);
-        if (object.lastName != null)
-            message.lastName = String(object.lastName);
-        if (object.about != null)
-            message.about = String(object.about);
-        if (object.coverPhoto != null)
-            message.coverPhoto = object.coverPhoto >>> 0;
-        if (object.avatarPhoto != null)
-            message.avatarPhoto = object.avatarPhoto >>> 0;
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a PersonMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof PersonMetadata
-     * @static
-     * @param {PersonMetadata} message PersonMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    PersonMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.firstName = "";
-            object.middleName = "";
-            object.lastName = "";
-            object.about = "";
-            object.coverPhoto = 0;
-            object.avatarPhoto = 0;
-        }
-        if (message.firstName != null && message.hasOwnProperty("firstName"))
-            object.firstName = message.firstName;
-        if (message.middleName != null && message.hasOwnProperty("middleName"))
-            object.middleName = message.middleName;
-        if (message.lastName != null && message.hasOwnProperty("lastName"))
-            object.lastName = message.lastName;
-        if (message.about != null && message.hasOwnProperty("about"))
-            object.about = message.about;
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            object.coverPhoto = message.coverPhoto;
-        if (message.avatarPhoto != null && message.hasOwnProperty("avatarPhoto"))
-            object.avatarPhoto = message.avatarPhoto;
-        return object;
-    };
-
-    /**
-     * Converts this PersonMetadata to JSON.
-     * @function toJSON
-     * @memberof PersonMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    PersonMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return PersonMetadata;
-})();
-
-$root.PlaylistMetadata = (function() {
-
-    /**
-     * Properties of a PlaylistMetadata.
-     * @exports IPlaylistMetadata
-     * @interface IPlaylistMetadata
-     * @property {string|null} [title] PlaylistMetadata title
-     * @property {Array.<Long>|null} [videos] PlaylistMetadata videos
-     */
-
-    /**
-     * Constructs a new PlaylistMetadata.
-     * @exports PlaylistMetadata
-     * @classdesc Represents a PlaylistMetadata.
-     * @implements IPlaylistMetadata
-     * @constructor
-     * @param {IPlaylistMetadata=} [properties] Properties to set
-     */
-    function PlaylistMetadata(properties) {
-        this.videos = [];
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * PlaylistMetadata title.
-     * @member {string} title
-     * @memberof PlaylistMetadata
-     * @instance
-     */
-    PlaylistMetadata.prototype.title = "";
-
-    /**
-     * PlaylistMetadata videos.
-     * @member {Array.<Long>} videos
-     * @memberof PlaylistMetadata
-     * @instance
-     */
-    PlaylistMetadata.prototype.videos = $util.emptyArray;
-
-    /**
-     * Creates a new PlaylistMetadata instance using the specified properties.
-     * @function create
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {IPlaylistMetadata=} [properties] Properties to set
-     * @returns {PlaylistMetadata} PlaylistMetadata instance
-     */
-    PlaylistMetadata.create = function create(properties) {
-        return new PlaylistMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified PlaylistMetadata message. Does not implicitly {@link PlaylistMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {IPlaylistMetadata} message PlaylistMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    PlaylistMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.title != null && Object.hasOwnProperty.call(message, "title"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
-        if (message.videos != null && message.videos.length)
-            for (var i = 0; i < message.videos.length; ++i)
-                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.videos[i]);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified PlaylistMetadata message, length delimited. Does not implicitly {@link PlaylistMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {IPlaylistMetadata} message PlaylistMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    PlaylistMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a PlaylistMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {PlaylistMetadata} PlaylistMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    PlaylistMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.PlaylistMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.title = reader.string();
-                break;
-            case 2:
-                if (!(message.videos && message.videos.length))
-                    message.videos = [];
-                if ((tag & 7) === 2) {
-                    var end2 = reader.uint32() + reader.pos;
-                    while (reader.pos < end2)
-                        message.videos.push(reader.uint64());
-                } else
-                    message.videos.push(reader.uint64());
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a PlaylistMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {PlaylistMetadata} PlaylistMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    PlaylistMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a PlaylistMetadata message.
-     * @function verify
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    PlaylistMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.title != null && message.hasOwnProperty("title"))
-            if (!$util.isString(message.title))
-                return "title: string expected";
-        if (message.videos != null && message.hasOwnProperty("videos")) {
-            if (!Array.isArray(message.videos))
-                return "videos: array expected";
-            for (var i = 0; i < message.videos.length; ++i)
-                if (!$util.isInteger(message.videos[i]) && !(message.videos[i] && $util.isInteger(message.videos[i].low) && $util.isInteger(message.videos[i].high)))
-                    return "videos: integer|Long[] expected";
-        }
-        return null;
-    };
-
-    /**
-     * Creates a PlaylistMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {PlaylistMetadata} PlaylistMetadata
-     */
-    PlaylistMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.PlaylistMetadata)
-            return object;
-        var message = new $root.PlaylistMetadata();
-        if (object.title != null)
-            message.title = String(object.title);
-        if (object.videos) {
-            if (!Array.isArray(object.videos))
-                throw TypeError(".PlaylistMetadata.videos: array expected");
-            message.videos = [];
-            for (var i = 0; i < object.videos.length; ++i)
-                if ($util.Long)
-                    (message.videos[i] = $util.Long.fromValue(object.videos[i])).unsigned = true;
-                else if (typeof object.videos[i] === "string")
-                    message.videos[i] = parseInt(object.videos[i], 10);
-                else if (typeof object.videos[i] === "number")
-                    message.videos[i] = object.videos[i];
-                else if (typeof object.videos[i] === "object")
-                    message.videos[i] = new $util.LongBits(object.videos[i].low >>> 0, object.videos[i].high >>> 0).toNumber(true);
-        }
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a PlaylistMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof PlaylistMetadata
-     * @static
-     * @param {PlaylistMetadata} message PlaylistMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    PlaylistMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.arrays || options.defaults)
-            object.videos = [];
-        if (options.defaults)
-            object.title = "";
-        if (message.title != null && message.hasOwnProperty("title"))
-            object.title = message.title;
-        if (message.videos && message.videos.length) {
-            object.videos = [];
-            for (var j = 0; j < message.videos.length; ++j)
-                if (typeof message.videos[j] === "number")
-                    object.videos[j] = options.longs === String ? String(message.videos[j]) : message.videos[j];
-                else
-                    object.videos[j] = options.longs === String ? $util.Long.prototype.toString.call(message.videos[j]) : options.longs === Number ? new $util.LongBits(message.videos[j].low >>> 0, message.videos[j].high >>> 0).toNumber(true) : message.videos[j];
-        }
-        return object;
-    };
-
-    /**
-     * Converts this PlaylistMetadata to JSON.
-     * @function toJSON
-     * @memberof PlaylistMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    PlaylistMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return PlaylistMetadata;
-})();
-
-$root.SeriesMetadata = (function() {
-
-    /**
-     * Properties of a SeriesMetadata.
-     * @exports ISeriesMetadata
-     * @interface ISeriesMetadata
-     * @property {string|null} [title] SeriesMetadata title
-     * @property {string|null} [description] SeriesMetadata description
-     * @property {number|null} [coverPhoto] SeriesMetadata coverPhoto
-     * @property {Array.<Long>|null} [persons] SeriesMetadata persons
-     */
-
-    /**
-     * Constructs a new SeriesMetadata.
-     * @exports SeriesMetadata
-     * @classdesc Represents a SeriesMetadata.
-     * @implements ISeriesMetadata
-     * @constructor
-     * @param {ISeriesMetadata=} [properties] Properties to set
-     */
-    function SeriesMetadata(properties) {
-        this.persons = [];
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * SeriesMetadata title.
-     * @member {string} title
-     * @memberof SeriesMetadata
-     * @instance
-     */
-    SeriesMetadata.prototype.title = "";
-
-    /**
-     * SeriesMetadata description.
-     * @member {string} description
-     * @memberof SeriesMetadata
-     * @instance
-     */
-    SeriesMetadata.prototype.description = "";
-
-    /**
-     * SeriesMetadata coverPhoto.
-     * @member {number} coverPhoto
-     * @memberof SeriesMetadata
-     * @instance
-     */
-    SeriesMetadata.prototype.coverPhoto = 0;
-
-    /**
-     * SeriesMetadata persons.
-     * @member {Array.<Long>} persons
-     * @memberof SeriesMetadata
-     * @instance
-     */
-    SeriesMetadata.prototype.persons = $util.emptyArray;
-
-    /**
-     * Creates a new SeriesMetadata instance using the specified properties.
-     * @function create
-     * @memberof SeriesMetadata
-     * @static
-     * @param {ISeriesMetadata=} [properties] Properties to set
-     * @returns {SeriesMetadata} SeriesMetadata instance
-     */
-    SeriesMetadata.create = function create(properties) {
-        return new SeriesMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified SeriesMetadata message. Does not implicitly {@link SeriesMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof SeriesMetadata
-     * @static
-     * @param {ISeriesMetadata} message SeriesMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    SeriesMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.title != null && Object.hasOwnProperty.call(message, "title"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
-        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
-        if (message.coverPhoto != null && Object.hasOwnProperty.call(message, "coverPhoto"))
-            writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.coverPhoto);
-        if (message.persons != null && message.persons.length) {
-            writer.uint32(/* id 4, wireType 2 =*/34).fork();
-            for (var i = 0; i < message.persons.length; ++i)
-                writer.uint64(message.persons[i]);
-            writer.ldelim();
-        }
-        return writer;
-    };
-
-    /**
-     * Encodes the specified SeriesMetadata message, length delimited. Does not implicitly {@link SeriesMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof SeriesMetadata
-     * @static
-     * @param {ISeriesMetadata} message SeriesMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    SeriesMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a SeriesMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof SeriesMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {SeriesMetadata} SeriesMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    SeriesMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.SeriesMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.title = reader.string();
-                break;
-            case 2:
-                message.description = reader.string();
-                break;
-            case 3:
-                message.coverPhoto = reader.uint32();
-                break;
-            case 4:
-                if (!(message.persons && message.persons.length))
-                    message.persons = [];
-                if ((tag & 7) === 2) {
-                    var end2 = reader.uint32() + reader.pos;
-                    while (reader.pos < end2)
-                        message.persons.push(reader.uint64());
-                } else
-                    message.persons.push(reader.uint64());
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a SeriesMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof SeriesMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {SeriesMetadata} SeriesMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    SeriesMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a SeriesMetadata message.
-     * @function verify
-     * @memberof SeriesMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    SeriesMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.title != null && message.hasOwnProperty("title"))
-            if (!$util.isString(message.title))
-                return "title: string expected";
-        if (message.description != null && message.hasOwnProperty("description"))
-            if (!$util.isString(message.description))
-                return "description: string expected";
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            if (!$util.isInteger(message.coverPhoto))
-                return "coverPhoto: integer expected";
-        if (message.persons != null && message.hasOwnProperty("persons")) {
-            if (!Array.isArray(message.persons))
-                return "persons: array expected";
-            for (var i = 0; i < message.persons.length; ++i)
-                if (!$util.isInteger(message.persons[i]) && !(message.persons[i] && $util.isInteger(message.persons[i].low) && $util.isInteger(message.persons[i].high)))
-                    return "persons: integer|Long[] expected";
-        }
-        return null;
-    };
-
-    /**
-     * Creates a SeriesMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof SeriesMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {SeriesMetadata} SeriesMetadata
-     */
-    SeriesMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.SeriesMetadata)
-            return object;
-        var message = new $root.SeriesMetadata();
-        if (object.title != null)
-            message.title = String(object.title);
-        if (object.description != null)
-            message.description = String(object.description);
-        if (object.coverPhoto != null)
-            message.coverPhoto = object.coverPhoto >>> 0;
-        if (object.persons) {
-            if (!Array.isArray(object.persons))
-                throw TypeError(".SeriesMetadata.persons: array expected");
-            message.persons = [];
-            for (var i = 0; i < object.persons.length; ++i)
-                if ($util.Long)
-                    (message.persons[i] = $util.Long.fromValue(object.persons[i])).unsigned = true;
-                else if (typeof object.persons[i] === "string")
-                    message.persons[i] = parseInt(object.persons[i], 10);
-                else if (typeof object.persons[i] === "number")
-                    message.persons[i] = object.persons[i];
-                else if (typeof object.persons[i] === "object")
-                    message.persons[i] = new $util.LongBits(object.persons[i].low >>> 0, object.persons[i].high >>> 0).toNumber(true);
-        }
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a SeriesMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof SeriesMetadata
-     * @static
-     * @param {SeriesMetadata} message SeriesMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    SeriesMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.arrays || options.defaults)
-            object.persons = [];
-        if (options.defaults) {
-            object.title = "";
-            object.description = "";
-            object.coverPhoto = 0;
-        }
-        if (message.title != null && message.hasOwnProperty("title"))
-            object.title = message.title;
-        if (message.description != null && message.hasOwnProperty("description"))
-            object.description = message.description;
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            object.coverPhoto = message.coverPhoto;
-        if (message.persons && message.persons.length) {
-            object.persons = [];
-            for (var j = 0; j < message.persons.length; ++j)
-                if (typeof message.persons[j] === "number")
-                    object.persons[j] = options.longs === String ? String(message.persons[j]) : message.persons[j];
-                else
-                    object.persons[j] = options.longs === String ? $util.Long.prototype.toString.call(message.persons[j]) : options.longs === Number ? new $util.LongBits(message.persons[j].low >>> 0, message.persons[j].high >>> 0).toNumber(true) : message.persons[j];
-        }
-        return object;
-    };
-
-    /**
-     * Converts this SeriesMetadata to JSON.
-     * @function toJSON
-     * @memberof SeriesMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    SeriesMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return SeriesMetadata;
-})();
-
-$root.SeasonMetadata = (function() {
-
-    /**
-     * Properties of a SeasonMetadata.
-     * @exports ISeasonMetadata
-     * @interface ISeasonMetadata
-     * @property {string|null} [title] SeasonMetadata title
-     * @property {string|null} [description] SeasonMetadata description
-     * @property {number|null} [coverPhoto] SeasonMetadata coverPhoto
-     * @property {Array.<Long>|null} [persons] SeasonMetadata persons
-     */
-
-    /**
-     * Constructs a new SeasonMetadata.
-     * @exports SeasonMetadata
-     * @classdesc Represents a SeasonMetadata.
-     * @implements ISeasonMetadata
-     * @constructor
-     * @param {ISeasonMetadata=} [properties] Properties to set
-     */
-    function SeasonMetadata(properties) {
-        this.persons = [];
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * SeasonMetadata title.
-     * @member {string} title
-     * @memberof SeasonMetadata
-     * @instance
-     */
-    SeasonMetadata.prototype.title = "";
-
-    /**
-     * SeasonMetadata description.
-     * @member {string} description
-     * @memberof SeasonMetadata
-     * @instance
-     */
-    SeasonMetadata.prototype.description = "";
-
-    /**
-     * SeasonMetadata coverPhoto.
-     * @member {number} coverPhoto
-     * @memberof SeasonMetadata
-     * @instance
-     */
-    SeasonMetadata.prototype.coverPhoto = 0;
-
-    /**
-     * SeasonMetadata persons.
-     * @member {Array.<Long>} persons
-     * @memberof SeasonMetadata
-     * @instance
-     */
-    SeasonMetadata.prototype.persons = $util.emptyArray;
-
-    /**
-     * Creates a new SeasonMetadata instance using the specified properties.
-     * @function create
-     * @memberof SeasonMetadata
-     * @static
-     * @param {ISeasonMetadata=} [properties] Properties to set
-     * @returns {SeasonMetadata} SeasonMetadata instance
-     */
-    SeasonMetadata.create = function create(properties) {
-        return new SeasonMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified SeasonMetadata message. Does not implicitly {@link SeasonMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof SeasonMetadata
-     * @static
-     * @param {ISeasonMetadata} message SeasonMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    SeasonMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.title != null && Object.hasOwnProperty.call(message, "title"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
-        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
-        if (message.coverPhoto != null && Object.hasOwnProperty.call(message, "coverPhoto"))
-            writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.coverPhoto);
-        if (message.persons != null && message.persons.length) {
-            writer.uint32(/* id 4, wireType 2 =*/34).fork();
-            for (var i = 0; i < message.persons.length; ++i)
-                writer.uint64(message.persons[i]);
-            writer.ldelim();
-        }
-        return writer;
-    };
-
-    /**
-     * Encodes the specified SeasonMetadata message, length delimited. Does not implicitly {@link SeasonMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof SeasonMetadata
-     * @static
-     * @param {ISeasonMetadata} message SeasonMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    SeasonMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a SeasonMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof SeasonMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {SeasonMetadata} SeasonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    SeasonMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.SeasonMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.title = reader.string();
-                break;
-            case 2:
-                message.description = reader.string();
-                break;
-            case 3:
-                message.coverPhoto = reader.uint32();
-                break;
-            case 4:
-                if (!(message.persons && message.persons.length))
-                    message.persons = [];
-                if ((tag & 7) === 2) {
-                    var end2 = reader.uint32() + reader.pos;
-                    while (reader.pos < end2)
-                        message.persons.push(reader.uint64());
-                } else
-                    message.persons.push(reader.uint64());
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a SeasonMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof SeasonMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {SeasonMetadata} SeasonMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    SeasonMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a SeasonMetadata message.
-     * @function verify
-     * @memberof SeasonMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    SeasonMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.title != null && message.hasOwnProperty("title"))
-            if (!$util.isString(message.title))
-                return "title: string expected";
-        if (message.description != null && message.hasOwnProperty("description"))
-            if (!$util.isString(message.description))
-                return "description: string expected";
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            if (!$util.isInteger(message.coverPhoto))
-                return "coverPhoto: integer expected";
-        if (message.persons != null && message.hasOwnProperty("persons")) {
-            if (!Array.isArray(message.persons))
-                return "persons: array expected";
-            for (var i = 0; i < message.persons.length; ++i)
-                if (!$util.isInteger(message.persons[i]) && !(message.persons[i] && $util.isInteger(message.persons[i].low) && $util.isInteger(message.persons[i].high)))
-                    return "persons: integer|Long[] expected";
-        }
-        return null;
-    };
-
-    /**
-     * Creates a SeasonMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof SeasonMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {SeasonMetadata} SeasonMetadata
-     */
-    SeasonMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.SeasonMetadata)
-            return object;
-        var message = new $root.SeasonMetadata();
-        if (object.title != null)
-            message.title = String(object.title);
-        if (object.description != null)
-            message.description = String(object.description);
-        if (object.coverPhoto != null)
-            message.coverPhoto = object.coverPhoto >>> 0;
-        if (object.persons) {
-            if (!Array.isArray(object.persons))
-                throw TypeError(".SeasonMetadata.persons: array expected");
-            message.persons = [];
-            for (var i = 0; i < object.persons.length; ++i)
-                if ($util.Long)
-                    (message.persons[i] = $util.Long.fromValue(object.persons[i])).unsigned = true;
-                else if (typeof object.persons[i] === "string")
-                    message.persons[i] = parseInt(object.persons[i], 10);
-                else if (typeof object.persons[i] === "number")
-                    message.persons[i] = object.persons[i];
-                else if (typeof object.persons[i] === "object")
-                    message.persons[i] = new $util.LongBits(object.persons[i].low >>> 0, object.persons[i].high >>> 0).toNumber(true);
-        }
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a SeasonMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof SeasonMetadata
-     * @static
-     * @param {SeasonMetadata} message SeasonMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    SeasonMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.arrays || options.defaults)
-            object.persons = [];
-        if (options.defaults) {
-            object.title = "";
-            object.description = "";
-            object.coverPhoto = 0;
-        }
-        if (message.title != null && message.hasOwnProperty("title"))
-            object.title = message.title;
-        if (message.description != null && message.hasOwnProperty("description"))
-            object.description = message.description;
-        if (message.coverPhoto != null && message.hasOwnProperty("coverPhoto"))
-            object.coverPhoto = message.coverPhoto;
-        if (message.persons && message.persons.length) {
-            object.persons = [];
-            for (var j = 0; j < message.persons.length; ++j)
-                if (typeof message.persons[j] === "number")
-                    object.persons[j] = options.longs === String ? String(message.persons[j]) : message.persons[j];
-                else
-                    object.persons[j] = options.longs === String ? $util.Long.prototype.toString.call(message.persons[j]) : options.longs === Number ? new $util.LongBits(message.persons[j].low >>> 0, message.persons[j].high >>> 0).toNumber(true) : message.persons[j];
-        }
-        return object;
-    };
-
-    /**
-     * Converts this SeasonMetadata to JSON.
-     * @function toJSON
-     * @memberof SeasonMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    SeasonMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return SeasonMetadata;
-})();
-
-$root.GeoCoordiantes = (function() {
-
-    /**
-     * Properties of a GeoCoordiantes.
-     * @exports IGeoCoordiantes
-     * @interface IGeoCoordiantes
-     * @property {number|null} [latitude] GeoCoordiantes latitude
-     * @property {number|null} [longitude] GeoCoordiantes longitude
-     */
-
-    /**
-     * Constructs a new GeoCoordiantes.
-     * @exports GeoCoordiantes
-     * @classdesc Represents a GeoCoordiantes.
-     * @implements IGeoCoordiantes
-     * @constructor
-     * @param {IGeoCoordiantes=} [properties] Properties to set
-     */
-    function GeoCoordiantes(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * GeoCoordiantes latitude.
-     * @member {number} latitude
-     * @memberof GeoCoordiantes
-     * @instance
-     */
-    GeoCoordiantes.prototype.latitude = 0;
-
-    /**
-     * GeoCoordiantes longitude.
-     * @member {number} longitude
-     * @memberof GeoCoordiantes
-     * @instance
-     */
-    GeoCoordiantes.prototype.longitude = 0;
-
-    /**
-     * Creates a new GeoCoordiantes instance using the specified properties.
-     * @function create
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {IGeoCoordiantes=} [properties] Properties to set
-     * @returns {GeoCoordiantes} GeoCoordiantes instance
-     */
-    GeoCoordiantes.create = function create(properties) {
-        return new GeoCoordiantes(properties);
-    };
-
-    /**
-     * Encodes the specified GeoCoordiantes message. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @function encode
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {IGeoCoordiantes} message GeoCoordiantes message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    GeoCoordiantes.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.latitude != null && Object.hasOwnProperty.call(message, "latitude"))
-            writer.uint32(/* id 3, wireType 5 =*/29).float(message.latitude);
-        if (message.longitude != null && Object.hasOwnProperty.call(message, "longitude"))
-            writer.uint32(/* id 4, wireType 5 =*/37).float(message.longitude);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified GeoCoordiantes message, length delimited. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {IGeoCoordiantes} message GeoCoordiantes message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    GeoCoordiantes.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer.
-     * @function decode
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {GeoCoordiantes} GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    GeoCoordiantes.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.GeoCoordiantes();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 3:
-                message.latitude = reader.float();
-                break;
-            case 4:
-                message.longitude = reader.float();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {GeoCoordiantes} GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    GeoCoordiantes.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a GeoCoordiantes message.
-     * @function verify
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    GeoCoordiantes.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.latitude != null && message.hasOwnProperty("latitude"))
-            if (typeof message.latitude !== "number")
-                return "latitude: number expected";
-        if (message.longitude != null && message.hasOwnProperty("longitude"))
-            if (typeof message.longitude !== "number")
-                return "longitude: number expected";
-        return null;
-    };
-
-    /**
-     * Creates a GeoCoordiantes message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {GeoCoordiantes} GeoCoordiantes
-     */
-    GeoCoordiantes.fromObject = function fromObject(object) {
-        if (object instanceof $root.GeoCoordiantes)
-            return object;
-        var message = new $root.GeoCoordiantes();
-        if (object.latitude != null)
-            message.latitude = Number(object.latitude);
-        if (object.longitude != null)
-            message.longitude = Number(object.longitude);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a GeoCoordiantes message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {GeoCoordiantes} message GeoCoordiantes
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    GeoCoordiantes.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.latitude = 0;
-            object.longitude = 0;
-        }
-        if (message.latitude != null && message.hasOwnProperty("latitude"))
-            object.latitude = options.json && !isFinite(message.latitude) ? String(message.latitude) : message.latitude;
-        if (message.longitude != null && message.hasOwnProperty("longitude"))
-            object.longitude = options.json && !isFinite(message.longitude) ? String(message.longitude) : message.longitude;
-        return object;
-    };
-
-    /**
-     * Converts this GeoCoordiantes to JSON.
-     * @function toJSON
-     * @memberof GeoCoordiantes
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    GeoCoordiantes.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return GeoCoordiantes;
-})();
-
-$root.NodeLocationMetadata = (function() {
-
-    /**
-     * Properties of a NodeLocationMetadata.
-     * @exports INodeLocationMetadata
-     * @interface INodeLocationMetadata
-     * @property {string|null} [countryCode] NodeLocationMetadata countryCode
-     * @property {string|null} [city] NodeLocationMetadata city
-     * @property {IGeoCoordiantes|null} [coordinates] NodeLocationMetadata coordinates
-     */
-
-    /**
-     * Constructs a new NodeLocationMetadata.
-     * @exports NodeLocationMetadata
-     * @classdesc Represents a NodeLocationMetadata.
-     * @implements INodeLocationMetadata
-     * @constructor
-     * @param {INodeLocationMetadata=} [properties] Properties to set
-     */
-    function NodeLocationMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * NodeLocationMetadata countryCode.
-     * @member {string} countryCode
-     * @memberof NodeLocationMetadata
-     * @instance
-     */
-    NodeLocationMetadata.prototype.countryCode = "";
-
-    /**
-     * NodeLocationMetadata city.
-     * @member {string} city
-     * @memberof NodeLocationMetadata
-     * @instance
-     */
-    NodeLocationMetadata.prototype.city = "";
-
-    /**
-     * NodeLocationMetadata coordinates.
-     * @member {IGeoCoordiantes|null|undefined} coordinates
-     * @memberof NodeLocationMetadata
-     * @instance
-     */
-    NodeLocationMetadata.prototype.coordinates = null;
-
-    /**
-     * Creates a new NodeLocationMetadata instance using the specified properties.
-     * @function create
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {INodeLocationMetadata=} [properties] Properties to set
-     * @returns {NodeLocationMetadata} NodeLocationMetadata instance
-     */
-    NodeLocationMetadata.create = function create(properties) {
-        return new NodeLocationMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified NodeLocationMetadata message. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {INodeLocationMetadata} message NodeLocationMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    NodeLocationMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.countryCode != null && Object.hasOwnProperty.call(message, "countryCode"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.countryCode);
-        if (message.city != null && Object.hasOwnProperty.call(message, "city"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.city);
-        if (message.coordinates != null && Object.hasOwnProperty.call(message, "coordinates"))
-            $root.GeoCoordiantes.encode(message.coordinates, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
-        return writer;
-    };
-
-    /**
-     * Encodes the specified NodeLocationMetadata message, length delimited. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {INodeLocationMetadata} message NodeLocationMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    NodeLocationMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {NodeLocationMetadata} NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    NodeLocationMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.NodeLocationMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.countryCode = reader.string();
-                break;
-            case 2:
-                message.city = reader.string();
-                break;
-            case 3:
-                message.coordinates = $root.GeoCoordiantes.decode(reader, reader.uint32());
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {NodeLocationMetadata} NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    NodeLocationMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a NodeLocationMetadata message.
-     * @function verify
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    NodeLocationMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.countryCode != null && message.hasOwnProperty("countryCode"))
-            if (!$util.isString(message.countryCode))
-                return "countryCode: string expected";
-        if (message.city != null && message.hasOwnProperty("city"))
-            if (!$util.isString(message.city))
-                return "city: string expected";
-        if (message.coordinates != null && message.hasOwnProperty("coordinates")) {
-            var error = $root.GeoCoordiantes.verify(message.coordinates);
-            if (error)
-                return "coordinates." + error;
-        }
-        return null;
-    };
-
-    /**
-     * Creates a NodeLocationMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {NodeLocationMetadata} NodeLocationMetadata
-     */
-    NodeLocationMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.NodeLocationMetadata)
-            return object;
-        var message = new $root.NodeLocationMetadata();
-        if (object.countryCode != null)
-            message.countryCode = String(object.countryCode);
-        if (object.city != null)
-            message.city = String(object.city);
-        if (object.coordinates != null) {
-            if (typeof object.coordinates !== "object")
-                throw TypeError(".NodeLocationMetadata.coordinates: object expected");
-            message.coordinates = $root.GeoCoordiantes.fromObject(object.coordinates);
-        }
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a NodeLocationMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {NodeLocationMetadata} message NodeLocationMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    NodeLocationMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.countryCode = "";
-            object.city = "";
-            object.coordinates = null;
-        }
-        if (message.countryCode != null && message.hasOwnProperty("countryCode"))
-            object.countryCode = message.countryCode;
-        if (message.city != null && message.hasOwnProperty("city"))
-            object.city = message.city;
-        if (message.coordinates != null && message.hasOwnProperty("coordinates"))
-            object.coordinates = $root.GeoCoordiantes.toObject(message.coordinates, options);
-        return object;
-    };
-
-    /**
-     * Converts this NodeLocationMetadata to JSON.
-     * @function toJSON
-     * @memberof NodeLocationMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    NodeLocationMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return NodeLocationMetadata;
-})();
-
-$root.StorageBucketOperatorMetadata = (function() {
-
-    /**
-     * Properties of a StorageBucketOperatorMetadata.
-     * @exports IStorageBucketOperatorMetadata
-     * @interface IStorageBucketOperatorMetadata
-     * @property {string|null} [endpoint] StorageBucketOperatorMetadata endpoint
-     * @property {INodeLocationMetadata|null} [location] StorageBucketOperatorMetadata location
-     * @property {string|null} [extra] StorageBucketOperatorMetadata extra
-     */
-
-    /**
-     * Constructs a new StorageBucketOperatorMetadata.
-     * @exports StorageBucketOperatorMetadata
-     * @classdesc Represents a StorageBucketOperatorMetadata.
-     * @implements IStorageBucketOperatorMetadata
-     * @constructor
-     * @param {IStorageBucketOperatorMetadata=} [properties] Properties to set
-     */
-    function StorageBucketOperatorMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * StorageBucketOperatorMetadata endpoint.
-     * @member {string} endpoint
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     */
-    StorageBucketOperatorMetadata.prototype.endpoint = "";
-
-    /**
-     * StorageBucketOperatorMetadata location.
-     * @member {INodeLocationMetadata|null|undefined} location
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     */
-    StorageBucketOperatorMetadata.prototype.location = null;
-
-    /**
-     * StorageBucketOperatorMetadata extra.
-     * @member {string} extra
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     */
-    StorageBucketOperatorMetadata.prototype.extra = "";
-
-    /**
-     * Creates a new StorageBucketOperatorMetadata instance using the specified properties.
-     * @function create
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {IStorageBucketOperatorMetadata=} [properties] Properties to set
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata instance
-     */
-    StorageBucketOperatorMetadata.create = function create(properties) {
-        return new StorageBucketOperatorMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {IStorageBucketOperatorMetadata} message StorageBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    StorageBucketOperatorMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.endpoint != null && Object.hasOwnProperty.call(message, "endpoint"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.endpoint);
-        if (message.location != null && Object.hasOwnProperty.call(message, "location"))
-            $root.NodeLocationMetadata.encode(message.location, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
-        if (message.extra != null && Object.hasOwnProperty.call(message, "extra"))
-            writer.uint32(/* id 3, wireType 2 =*/26).string(message.extra);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message, length delimited. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {IStorageBucketOperatorMetadata} message StorageBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    StorageBucketOperatorMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    StorageBucketOperatorMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.StorageBucketOperatorMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.endpoint = reader.string();
-                break;
-            case 2:
-                message.location = $root.NodeLocationMetadata.decode(reader, reader.uint32());
-                break;
-            case 3:
-                message.extra = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    StorageBucketOperatorMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a StorageBucketOperatorMetadata message.
-     * @function verify
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    StorageBucketOperatorMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            if (!$util.isString(message.endpoint))
-                return "endpoint: string expected";
-        if (message.location != null && message.hasOwnProperty("location")) {
-            var error = $root.NodeLocationMetadata.verify(message.location);
-            if (error)
-                return "location." + error;
-        }
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            if (!$util.isString(message.extra))
-                return "extra: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a StorageBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata
-     */
-    StorageBucketOperatorMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.StorageBucketOperatorMetadata)
-            return object;
-        var message = new $root.StorageBucketOperatorMetadata();
-        if (object.endpoint != null)
-            message.endpoint = String(object.endpoint);
-        if (object.location != null) {
-            if (typeof object.location !== "object")
-                throw TypeError(".StorageBucketOperatorMetadata.location: object expected");
-            message.location = $root.NodeLocationMetadata.fromObject(object.location);
-        }
-        if (object.extra != null)
-            message.extra = String(object.extra);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a StorageBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {StorageBucketOperatorMetadata} message StorageBucketOperatorMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    StorageBucketOperatorMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.endpoint = "";
-            object.location = null;
-            object.extra = "";
-        }
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            object.endpoint = message.endpoint;
-        if (message.location != null && message.hasOwnProperty("location"))
-            object.location = $root.NodeLocationMetadata.toObject(message.location, options);
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            object.extra = message.extra;
-        return object;
-    };
-
-    /**
-     * Converts this StorageBucketOperatorMetadata to JSON.
-     * @function toJSON
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    StorageBucketOperatorMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return StorageBucketOperatorMetadata;
-})();
-
-$root.DistributionBucketOperatorMetadata = (function() {
-
-    /**
-     * Properties of a DistributionBucketOperatorMetadata.
-     * @exports IDistributionBucketOperatorMetadata
-     * @interface IDistributionBucketOperatorMetadata
-     * @property {string|null} [endpoint] DistributionBucketOperatorMetadata endpoint
-     * @property {INodeLocationMetadata|null} [location] DistributionBucketOperatorMetadata location
-     * @property {string|null} [extra] DistributionBucketOperatorMetadata extra
-     */
-
-    /**
-     * Constructs a new DistributionBucketOperatorMetadata.
-     * @exports DistributionBucketOperatorMetadata
-     * @classdesc Represents a DistributionBucketOperatorMetadata.
-     * @implements IDistributionBucketOperatorMetadata
-     * @constructor
-     * @param {IDistributionBucketOperatorMetadata=} [properties] Properties to set
-     */
-    function DistributionBucketOperatorMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * DistributionBucketOperatorMetadata endpoint.
-     * @member {string} endpoint
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     */
-    DistributionBucketOperatorMetadata.prototype.endpoint = "";
-
-    /**
-     * DistributionBucketOperatorMetadata location.
-     * @member {INodeLocationMetadata|null|undefined} location
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     */
-    DistributionBucketOperatorMetadata.prototype.location = null;
-
-    /**
-     * DistributionBucketOperatorMetadata extra.
-     * @member {string} extra
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     */
-    DistributionBucketOperatorMetadata.prototype.extra = "";
-
-    /**
-     * Creates a new DistributionBucketOperatorMetadata instance using the specified properties.
-     * @function create
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {IDistributionBucketOperatorMetadata=} [properties] Properties to set
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata instance
-     */
-    DistributionBucketOperatorMetadata.create = function create(properties) {
-        return new DistributionBucketOperatorMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {IDistributionBucketOperatorMetadata} message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketOperatorMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.endpoint != null && Object.hasOwnProperty.call(message, "endpoint"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.endpoint);
-        if (message.location != null && Object.hasOwnProperty.call(message, "location"))
-            $root.NodeLocationMetadata.encode(message.location, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
-        if (message.extra != null && Object.hasOwnProperty.call(message, "extra"))
-            writer.uint32(/* id 3, wireType 2 =*/26).string(message.extra);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message, length delimited. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {IDistributionBucketOperatorMetadata} message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketOperatorMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketOperatorMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.DistributionBucketOperatorMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.endpoint = reader.string();
-                break;
-            case 2:
-                message.location = $root.NodeLocationMetadata.decode(reader, reader.uint32());
-                break;
-            case 3:
-                message.extra = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketOperatorMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a DistributionBucketOperatorMetadata message.
-     * @function verify
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    DistributionBucketOperatorMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            if (!$util.isString(message.endpoint))
-                return "endpoint: string expected";
-        if (message.location != null && message.hasOwnProperty("location")) {
-            var error = $root.NodeLocationMetadata.verify(message.location);
-            if (error)
-                return "location." + error;
-        }
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            if (!$util.isString(message.extra))
-                return "extra: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a DistributionBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata
-     */
-    DistributionBucketOperatorMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.DistributionBucketOperatorMetadata)
-            return object;
-        var message = new $root.DistributionBucketOperatorMetadata();
-        if (object.endpoint != null)
-            message.endpoint = String(object.endpoint);
-        if (object.location != null) {
-            if (typeof object.location !== "object")
-                throw TypeError(".DistributionBucketOperatorMetadata.location: object expected");
-            message.location = $root.NodeLocationMetadata.fromObject(object.location);
-        }
-        if (object.extra != null)
-            message.extra = String(object.extra);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a DistributionBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {DistributionBucketOperatorMetadata} message DistributionBucketOperatorMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    DistributionBucketOperatorMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.endpoint = "";
-            object.location = null;
-            object.extra = "";
-        }
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            object.endpoint = message.endpoint;
-        if (message.location != null && message.hasOwnProperty("location"))
-            object.location = $root.NodeLocationMetadata.toObject(message.location, options);
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            object.extra = message.extra;
-        return object;
-    };
-
-    /**
-     * Converts this DistributionBucketOperatorMetadata to JSON.
-     * @function toJSON
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    DistributionBucketOperatorMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return DistributionBucketOperatorMetadata;
-})();
-
-$root.DistributionBucketFamilyMetadata = (function() {
-
-    /**
-     * Properties of a DistributionBucketFamilyMetadata.
-     * @exports IDistributionBucketFamilyMetadata
-     * @interface IDistributionBucketFamilyMetadata
-     * @property {string|null} [region] DistributionBucketFamilyMetadata region
-     * @property {string|null} [description] DistributionBucketFamilyMetadata description
-     * @property {Array.<IGeoCoordiantes>|null} [boundary] DistributionBucketFamilyMetadata boundary
-     */
-
-    /**
-     * Constructs a new DistributionBucketFamilyMetadata.
-     * @exports DistributionBucketFamilyMetadata
-     * @classdesc Represents a DistributionBucketFamilyMetadata.
-     * @implements IDistributionBucketFamilyMetadata
-     * @constructor
-     * @param {IDistributionBucketFamilyMetadata=} [properties] Properties to set
-     */
-    function DistributionBucketFamilyMetadata(properties) {
-        this.boundary = [];
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * DistributionBucketFamilyMetadata region.
-     * @member {string} region
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     */
-    DistributionBucketFamilyMetadata.prototype.region = "";
-
-    /**
-     * DistributionBucketFamilyMetadata description.
-     * @member {string} description
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     */
-    DistributionBucketFamilyMetadata.prototype.description = "";
-
-    /**
-     * DistributionBucketFamilyMetadata boundary.
-     * @member {Array.<IGeoCoordiantes>} boundary
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     */
-    DistributionBucketFamilyMetadata.prototype.boundary = $util.emptyArray;
-
-    /**
-     * Creates a new DistributionBucketFamilyMetadata instance using the specified properties.
-     * @function create
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {IDistributionBucketFamilyMetadata=} [properties] Properties to set
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata instance
-     */
-    DistributionBucketFamilyMetadata.create = function create(properties) {
-        return new DistributionBucketFamilyMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {IDistributionBucketFamilyMetadata} message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketFamilyMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.region != null && Object.hasOwnProperty.call(message, "region"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.region);
-        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
-        if (message.boundary != null && message.boundary.length)
-            for (var i = 0; i < message.boundary.length; ++i)
-                $root.GeoCoordiantes.encode(message.boundary[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
-        return writer;
-    };
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message, length delimited. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {IDistributionBucketFamilyMetadata} message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketFamilyMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketFamilyMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.DistributionBucketFamilyMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.region = reader.string();
-                break;
-            case 2:
-                message.description = reader.string();
-                break;
-            case 3:
-                if (!(message.boundary && message.boundary.length))
-                    message.boundary = [];
-                message.boundary.push($root.GeoCoordiantes.decode(reader, reader.uint32()));
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketFamilyMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a DistributionBucketFamilyMetadata message.
-     * @function verify
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    DistributionBucketFamilyMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.region != null && message.hasOwnProperty("region"))
-            if (!$util.isString(message.region))
-                return "region: string expected";
-        if (message.description != null && message.hasOwnProperty("description"))
-            if (!$util.isString(message.description))
-                return "description: string expected";
-        if (message.boundary != null && message.hasOwnProperty("boundary")) {
-            if (!Array.isArray(message.boundary))
-                return "boundary: array expected";
-            for (var i = 0; i < message.boundary.length; ++i) {
-                var error = $root.GeoCoordiantes.verify(message.boundary[i]);
-                if (error)
-                    return "boundary." + error;
-            }
-        }
-        return null;
-    };
-
-    /**
-     * Creates a DistributionBucketFamilyMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata
-     */
-    DistributionBucketFamilyMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.DistributionBucketFamilyMetadata)
-            return object;
-        var message = new $root.DistributionBucketFamilyMetadata();
-        if (object.region != null)
-            message.region = String(object.region);
-        if (object.description != null)
-            message.description = String(object.description);
-        if (object.boundary) {
-            if (!Array.isArray(object.boundary))
-                throw TypeError(".DistributionBucketFamilyMetadata.boundary: array expected");
-            message.boundary = [];
-            for (var i = 0; i < object.boundary.length; ++i) {
-                if (typeof object.boundary[i] !== "object")
-                    throw TypeError(".DistributionBucketFamilyMetadata.boundary: object expected");
-                message.boundary[i] = $root.GeoCoordiantes.fromObject(object.boundary[i]);
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a DistributionBucketFamilyMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {DistributionBucketFamilyMetadata} message DistributionBucketFamilyMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    DistributionBucketFamilyMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.arrays || options.defaults)
-            object.boundary = [];
-        if (options.defaults) {
-            object.region = "";
-            object.description = "";
-        }
-        if (message.region != null && message.hasOwnProperty("region"))
-            object.region = message.region;
-        if (message.description != null && message.hasOwnProperty("description"))
-            object.description = message.description;
-        if (message.boundary && message.boundary.length) {
-            object.boundary = [];
-            for (var j = 0; j < message.boundary.length; ++j)
-                object.boundary[j] = $root.GeoCoordiantes.toObject(message.boundary[j], options);
-        }
-        return object;
-    };
-
-    /**
-     * Converts this DistributionBucketFamilyMetadata to JSON.
-     * @function toJSON
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    DistributionBucketFamilyMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return DistributionBucketFamilyMetadata;
-})();
-
-$root.PublishedBeforeJoystream = (function() {
-
-    /**
-     * Properties of a PublishedBeforeJoystream.
-     * @exports IPublishedBeforeJoystream
-     * @interface IPublishedBeforeJoystream
-     * @property {boolean|null} [isPublished] PublishedBeforeJoystream isPublished
-     * @property {string|null} [date] PublishedBeforeJoystream date
-     */
-
-    /**
-     * Constructs a new PublishedBeforeJoystream.
-     * @exports PublishedBeforeJoystream
-     * @classdesc Represents a PublishedBeforeJoystream.
-     * @implements IPublishedBeforeJoystream
-     * @constructor
-     * @param {IPublishedBeforeJoystream=} [properties] Properties to set
-     */
-    function PublishedBeforeJoystream(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * PublishedBeforeJoystream isPublished.
-     * @member {boolean} isPublished
-     * @memberof PublishedBeforeJoystream
-     * @instance
-     */
-    PublishedBeforeJoystream.prototype.isPublished = false;
-
-    /**
-     * PublishedBeforeJoystream date.
-     * @member {string} date
-     * @memberof PublishedBeforeJoystream
-     * @instance
-     */
-    PublishedBeforeJoystream.prototype.date = "";
-
-    /**
-     * Creates a new PublishedBeforeJoystream instance using the specified properties.
-     * @function create
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {IPublishedBeforeJoystream=} [properties] Properties to set
-     * @returns {PublishedBeforeJoystream} PublishedBeforeJoystream instance
-     */
-    PublishedBeforeJoystream.create = function create(properties) {
-        return new PublishedBeforeJoystream(properties);
-    };
-
-    /**
-     * Encodes the specified PublishedBeforeJoystream message. Does not implicitly {@link PublishedBeforeJoystream.verify|verify} messages.
-     * @function encode
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {IPublishedBeforeJoystream} message PublishedBeforeJoystream message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    PublishedBeforeJoystream.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.isPublished != null && Object.hasOwnProperty.call(message, "isPublished"))
-            writer.uint32(/* id 1, wireType 0 =*/8).bool(message.isPublished);
-        if (message.date != null && Object.hasOwnProperty.call(message, "date"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.date);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified PublishedBeforeJoystream message, length delimited. Does not implicitly {@link PublishedBeforeJoystream.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {IPublishedBeforeJoystream} message PublishedBeforeJoystream message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    PublishedBeforeJoystream.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a PublishedBeforeJoystream message from the specified reader or buffer.
-     * @function decode
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {PublishedBeforeJoystream} PublishedBeforeJoystream
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    PublishedBeforeJoystream.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.PublishedBeforeJoystream();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.isPublished = reader.bool();
-                break;
-            case 2:
-                message.date = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a PublishedBeforeJoystream message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {PublishedBeforeJoystream} PublishedBeforeJoystream
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    PublishedBeforeJoystream.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a PublishedBeforeJoystream message.
-     * @function verify
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    PublishedBeforeJoystream.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.isPublished != null && message.hasOwnProperty("isPublished"))
-            if (typeof message.isPublished !== "boolean")
-                return "isPublished: boolean expected";
-        if (message.date != null && message.hasOwnProperty("date"))
-            if (!$util.isString(message.date))
-                return "date: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a PublishedBeforeJoystream message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {PublishedBeforeJoystream} PublishedBeforeJoystream
-     */
-    PublishedBeforeJoystream.fromObject = function fromObject(object) {
-        if (object instanceof $root.PublishedBeforeJoystream)
-            return object;
-        var message = new $root.PublishedBeforeJoystream();
-        if (object.isPublished != null)
-            message.isPublished = Boolean(object.isPublished);
-        if (object.date != null)
-            message.date = String(object.date);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a PublishedBeforeJoystream message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof PublishedBeforeJoystream
-     * @static
-     * @param {PublishedBeforeJoystream} message PublishedBeforeJoystream
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    PublishedBeforeJoystream.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.isPublished = false;
-            object.date = "";
-        }
-        if (message.isPublished != null && message.hasOwnProperty("isPublished"))
-            object.isPublished = message.isPublished;
-        if (message.date != null && message.hasOwnProperty("date"))
-            object.date = message.date;
-        return object;
-    };
-
-    /**
-     * Converts this PublishedBeforeJoystream to JSON.
-     * @function toJSON
-     * @memberof PublishedBeforeJoystream
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    PublishedBeforeJoystream.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return PublishedBeforeJoystream;
-})();
-
-$root.License = (function() {
-
-    /**
-     * Properties of a License.
-     * @exports ILicense
-     * @interface ILicense
-     * @property {number|null} [code] License code
-     * @property {string|null} [attribution] License attribution
-     * @property {string|null} [customText] License customText
-     */
-
-    /**
-     * Constructs a new License.
-     * @exports License
-     * @classdesc Represents a License.
-     * @implements ILicense
-     * @constructor
-     * @param {ILicense=} [properties] Properties to set
-     */
-    function License(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * License code.
-     * @member {number} code
-     * @memberof License
-     * @instance
-     */
-    License.prototype.code = 0;
-
-    /**
-     * License attribution.
-     * @member {string} attribution
-     * @memberof License
-     * @instance
-     */
-    License.prototype.attribution = "";
-
-    /**
-     * License customText.
-     * @member {string} customText
-     * @memberof License
-     * @instance
-     */
-    License.prototype.customText = "";
-
-    /**
-     * Creates a new License instance using the specified properties.
-     * @function create
-     * @memberof License
-     * @static
-     * @param {ILicense=} [properties] Properties to set
-     * @returns {License} License instance
-     */
-    License.create = function create(properties) {
-        return new License(properties);
-    };
-
-    /**
-     * Encodes the specified License message. Does not implicitly {@link License.verify|verify} messages.
-     * @function encode
-     * @memberof License
-     * @static
-     * @param {ILicense} message License message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    License.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.code != null && Object.hasOwnProperty.call(message, "code"))
-            writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.code);
-        if (message.attribution != null && Object.hasOwnProperty.call(message, "attribution"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.attribution);
-        if (message.customText != null && Object.hasOwnProperty.call(message, "customText"))
-            writer.uint32(/* id 3, wireType 2 =*/26).string(message.customText);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified License message, length delimited. Does not implicitly {@link License.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof License
-     * @static
-     * @param {ILicense} message License message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    License.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a License message from the specified reader or buffer.
-     * @function decode
-     * @memberof License
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {License} License
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    License.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.License();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.code = reader.uint32();
-                break;
-            case 2:
-                message.attribution = reader.string();
-                break;
-            case 3:
-                message.customText = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a License message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof License
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {License} License
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    License.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a License message.
-     * @function verify
-     * @memberof License
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    License.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.code != null && message.hasOwnProperty("code"))
-            if (!$util.isInteger(message.code))
-                return "code: integer expected";
-        if (message.attribution != null && message.hasOwnProperty("attribution"))
-            if (!$util.isString(message.attribution))
-                return "attribution: string expected";
-        if (message.customText != null && message.hasOwnProperty("customText"))
-            if (!$util.isString(message.customText))
-                return "customText: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a License message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof License
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {License} License
-     */
-    License.fromObject = function fromObject(object) {
-        if (object instanceof $root.License)
-            return object;
-        var message = new $root.License();
-        if (object.code != null)
-            message.code = object.code >>> 0;
-        if (object.attribution != null)
-            message.attribution = String(object.attribution);
-        if (object.customText != null)
-            message.customText = String(object.customText);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a License message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof License
-     * @static
-     * @param {License} message License
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    License.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.code = 0;
-            object.attribution = "";
-            object.customText = "";
-        }
-        if (message.code != null && message.hasOwnProperty("code"))
-            object.code = message.code;
-        if (message.attribution != null && message.hasOwnProperty("attribution"))
-            object.attribution = message.attribution;
-        if (message.customText != null && message.hasOwnProperty("customText"))
-            object.customText = message.customText;
-        return object;
-    };
-
-    /**
-     * Converts this License to JSON.
-     * @function toJSON
-     * @memberof License
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    License.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return License;
-})();
-
-$root.MediaType = (function() {
-
-    /**
-     * Properties of a MediaType.
-     * @exports IMediaType
-     * @interface IMediaType
-     * @property {string|null} [codecName] MediaType codecName
-     * @property {string|null} [container] MediaType container
-     * @property {string|null} [mimeMediaType] MediaType mimeMediaType
-     */
-
-    /**
-     * Constructs a new MediaType.
-     * @exports MediaType
-     * @classdesc Represents a MediaType.
-     * @implements IMediaType
-     * @constructor
-     * @param {IMediaType=} [properties] Properties to set
-     */
-    function MediaType(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * MediaType codecName.
-     * @member {string} codecName
-     * @memberof MediaType
-     * @instance
-     */
-    MediaType.prototype.codecName = "";
-
-    /**
-     * MediaType container.
-     * @member {string} container
-     * @memberof MediaType
-     * @instance
-     */
-    MediaType.prototype.container = "";
-
-    /**
-     * MediaType mimeMediaType.
-     * @member {string} mimeMediaType
-     * @memberof MediaType
-     * @instance
-     */
-    MediaType.prototype.mimeMediaType = "";
-
-    /**
-     * Creates a new MediaType instance using the specified properties.
-     * @function create
-     * @memberof MediaType
-     * @static
-     * @param {IMediaType=} [properties] Properties to set
-     * @returns {MediaType} MediaType instance
-     */
-    MediaType.create = function create(properties) {
-        return new MediaType(properties);
-    };
-
-    /**
-     * Encodes the specified MediaType message. Does not implicitly {@link MediaType.verify|verify} messages.
-     * @function encode
-     * @memberof MediaType
-     * @static
-     * @param {IMediaType} message MediaType message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    MediaType.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.codecName != null && Object.hasOwnProperty.call(message, "codecName"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.codecName);
-        if (message.container != null && Object.hasOwnProperty.call(message, "container"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.container);
-        if (message.mimeMediaType != null && Object.hasOwnProperty.call(message, "mimeMediaType"))
-            writer.uint32(/* id 3, wireType 2 =*/26).string(message.mimeMediaType);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified MediaType message, length delimited. Does not implicitly {@link MediaType.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof MediaType
-     * @static
-     * @param {IMediaType} message MediaType message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    MediaType.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a MediaType message from the specified reader or buffer.
-     * @function decode
-     * @memberof MediaType
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {MediaType} MediaType
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    MediaType.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.MediaType();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.codecName = reader.string();
-                break;
-            case 2:
-                message.container = reader.string();
-                break;
-            case 3:
-                message.mimeMediaType = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a MediaType message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof MediaType
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {MediaType} MediaType
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    MediaType.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a MediaType message.
-     * @function verify
-     * @memberof MediaType
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    MediaType.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.codecName != null && message.hasOwnProperty("codecName"))
-            if (!$util.isString(message.codecName))
-                return "codecName: string expected";
-        if (message.container != null && message.hasOwnProperty("container"))
-            if (!$util.isString(message.container))
-                return "container: string expected";
-        if (message.mimeMediaType != null && message.hasOwnProperty("mimeMediaType"))
-            if (!$util.isString(message.mimeMediaType))
-                return "mimeMediaType: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a MediaType message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof MediaType
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {MediaType} MediaType
-     */
-    MediaType.fromObject = function fromObject(object) {
-        if (object instanceof $root.MediaType)
-            return object;
-        var message = new $root.MediaType();
-        if (object.codecName != null)
-            message.codecName = String(object.codecName);
-        if (object.container != null)
-            message.container = String(object.container);
-        if (object.mimeMediaType != null)
-            message.mimeMediaType = String(object.mimeMediaType);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a MediaType message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof MediaType
-     * @static
-     * @param {MediaType} message MediaType
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    MediaType.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.codecName = "";
-            object.container = "";
-            object.mimeMediaType = "";
-        }
-        if (message.codecName != null && message.hasOwnProperty("codecName"))
-            object.codecName = message.codecName;
-        if (message.container != null && message.hasOwnProperty("container"))
-            object.container = message.container;
-        if (message.mimeMediaType != null && message.hasOwnProperty("mimeMediaType"))
-            object.mimeMediaType = message.mimeMediaType;
-        return object;
-    };
-
-    /**
-     * Converts this MediaType to JSON.
-     * @function toJSON
-     * @memberof MediaType
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    MediaType.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return MediaType;
-})();
-
-$root.VideoMetadata = (function() {
-
-    /**
-     * Properties of a VideoMetadata.
-     * @exports IVideoMetadata
-     * @interface IVideoMetadata
-     * @property {string|null} [title] VideoMetadata title
-     * @property {string|null} [description] VideoMetadata description
-     * @property {number|null} [video] VideoMetadata video
-     * @property {number|null} [thumbnailPhoto] VideoMetadata thumbnailPhoto
-     * @property {number|null} [duration] VideoMetadata duration
-     * @property {number|null} [mediaPixelHeight] VideoMetadata mediaPixelHeight
-     * @property {number|null} [mediaPixelWidth] VideoMetadata mediaPixelWidth
-     * @property {IMediaType|null} [mediaType] VideoMetadata mediaType
-     * @property {string|null} [language] VideoMetadata language
-     * @property {ILicense|null} [license] VideoMetadata license
-     * @property {IPublishedBeforeJoystream|null} [publishedBeforeJoystream] VideoMetadata publishedBeforeJoystream
-     * @property {boolean|null} [hasMarketing] VideoMetadata hasMarketing
-     * @property {boolean|null} [isPublic] VideoMetadata isPublic
-     * @property {boolean|null} [isExplicit] VideoMetadata isExplicit
-     * @property {Array.<Long>|null} [persons] VideoMetadata persons
-     * @property {Long|null} [category] VideoMetadata category
-     */
-
-    /**
-     * Constructs a new VideoMetadata.
-     * @exports VideoMetadata
-     * @classdesc Represents a VideoMetadata.
-     * @implements IVideoMetadata
-     * @constructor
-     * @param {IVideoMetadata=} [properties] Properties to set
-     */
-    function VideoMetadata(properties) {
-        this.persons = [];
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * VideoMetadata title.
-     * @member {string} title
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.title = "";
-
-    /**
-     * VideoMetadata description.
-     * @member {string} description
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.description = "";
-
-    /**
-     * VideoMetadata video.
-     * @member {number} video
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.video = 0;
-
-    /**
-     * VideoMetadata thumbnailPhoto.
-     * @member {number} thumbnailPhoto
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.thumbnailPhoto = 0;
-
-    /**
-     * VideoMetadata duration.
-     * @member {number} duration
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.duration = 0;
-
-    /**
-     * VideoMetadata mediaPixelHeight.
-     * @member {number} mediaPixelHeight
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.mediaPixelHeight = 0;
-
-    /**
-     * VideoMetadata mediaPixelWidth.
-     * @member {number} mediaPixelWidth
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.mediaPixelWidth = 0;
-
-    /**
-     * VideoMetadata mediaType.
-     * @member {IMediaType|null|undefined} mediaType
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.mediaType = null;
-
-    /**
-     * VideoMetadata language.
-     * @member {string} language
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.language = "";
-
-    /**
-     * VideoMetadata license.
-     * @member {ILicense|null|undefined} license
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.license = null;
-
-    /**
-     * VideoMetadata publishedBeforeJoystream.
-     * @member {IPublishedBeforeJoystream|null|undefined} publishedBeforeJoystream
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.publishedBeforeJoystream = null;
-
-    /**
-     * VideoMetadata hasMarketing.
-     * @member {boolean} hasMarketing
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.hasMarketing = false;
-
-    /**
-     * VideoMetadata isPublic.
-     * @member {boolean} isPublic
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.isPublic = false;
-
-    /**
-     * VideoMetadata isExplicit.
-     * @member {boolean} isExplicit
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.isExplicit = false;
-
-    /**
-     * VideoMetadata persons.
-     * @member {Array.<Long>} persons
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.persons = $util.emptyArray;
-
-    /**
-     * VideoMetadata category.
-     * @member {Long} category
-     * @memberof VideoMetadata
-     * @instance
-     */
-    VideoMetadata.prototype.category = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
-
-    /**
-     * Creates a new VideoMetadata instance using the specified properties.
-     * @function create
-     * @memberof VideoMetadata
-     * @static
-     * @param {IVideoMetadata=} [properties] Properties to set
-     * @returns {VideoMetadata} VideoMetadata instance
-     */
-    VideoMetadata.create = function create(properties) {
-        return new VideoMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified VideoMetadata message. Does not implicitly {@link VideoMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof VideoMetadata
-     * @static
-     * @param {IVideoMetadata} message VideoMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    VideoMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.title != null && Object.hasOwnProperty.call(message, "title"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
-        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
-        if (message.video != null && Object.hasOwnProperty.call(message, "video"))
-            writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.video);
-        if (message.thumbnailPhoto != null && Object.hasOwnProperty.call(message, "thumbnailPhoto"))
-            writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.thumbnailPhoto);
-        if (message.duration != null && Object.hasOwnProperty.call(message, "duration"))
-            writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.duration);
-        if (message.mediaPixelHeight != null && Object.hasOwnProperty.call(message, "mediaPixelHeight"))
-            writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.mediaPixelHeight);
-        if (message.mediaPixelWidth != null && Object.hasOwnProperty.call(message, "mediaPixelWidth"))
-            writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.mediaPixelWidth);
-        if (message.mediaType != null && Object.hasOwnProperty.call(message, "mediaType"))
-            $root.MediaType.encode(message.mediaType, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
-        if (message.language != null && Object.hasOwnProperty.call(message, "language"))
-            writer.uint32(/* id 9, wireType 2 =*/74).string(message.language);
-        if (message.license != null && Object.hasOwnProperty.call(message, "license"))
-            $root.License.encode(message.license, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
-        if (message.publishedBeforeJoystream != null && Object.hasOwnProperty.call(message, "publishedBeforeJoystream"))
-            $root.PublishedBeforeJoystream.encode(message.publishedBeforeJoystream, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
-        if (message.hasMarketing != null && Object.hasOwnProperty.call(message, "hasMarketing"))
-            writer.uint32(/* id 12, wireType 0 =*/96).bool(message.hasMarketing);
-        if (message.isPublic != null && Object.hasOwnProperty.call(message, "isPublic"))
-            writer.uint32(/* id 13, wireType 0 =*/104).bool(message.isPublic);
-        if (message.isExplicit != null && Object.hasOwnProperty.call(message, "isExplicit"))
-            writer.uint32(/* id 14, wireType 0 =*/112).bool(message.isExplicit);
-        if (message.persons != null && message.persons.length) {
-            writer.uint32(/* id 15, wireType 2 =*/122).fork();
-            for (var i = 0; i < message.persons.length; ++i)
-                writer.uint64(message.persons[i]);
-            writer.ldelim();
-        }
-        if (message.category != null && Object.hasOwnProperty.call(message, "category"))
-            writer.uint32(/* id 16, wireType 0 =*/128).uint64(message.category);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified VideoMetadata message, length delimited. Does not implicitly {@link VideoMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof VideoMetadata
-     * @static
-     * @param {IVideoMetadata} message VideoMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    VideoMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a VideoMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof VideoMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {VideoMetadata} VideoMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    VideoMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.VideoMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.title = reader.string();
-                break;
-            case 2:
-                message.description = reader.string();
-                break;
-            case 3:
-                message.video = reader.uint32();
-                break;
-            case 4:
-                message.thumbnailPhoto = reader.uint32();
-                break;
-            case 5:
-                message.duration = reader.uint32();
-                break;
-            case 6:
-                message.mediaPixelHeight = reader.uint32();
-                break;
-            case 7:
-                message.mediaPixelWidth = reader.uint32();
-                break;
-            case 8:
-                message.mediaType = $root.MediaType.decode(reader, reader.uint32());
-                break;
-            case 9:
-                message.language = reader.string();
-                break;
-            case 10:
-                message.license = $root.License.decode(reader, reader.uint32());
-                break;
-            case 11:
-                message.publishedBeforeJoystream = $root.PublishedBeforeJoystream.decode(reader, reader.uint32());
-                break;
-            case 12:
-                message.hasMarketing = reader.bool();
-                break;
-            case 13:
-                message.isPublic = reader.bool();
-                break;
-            case 14:
-                message.isExplicit = reader.bool();
-                break;
-            case 15:
-                if (!(message.persons && message.persons.length))
-                    message.persons = [];
-                if ((tag & 7) === 2) {
-                    var end2 = reader.uint32() + reader.pos;
-                    while (reader.pos < end2)
-                        message.persons.push(reader.uint64());
-                } else
-                    message.persons.push(reader.uint64());
-                break;
-            case 16:
-                message.category = reader.uint64();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a VideoMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof VideoMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {VideoMetadata} VideoMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    VideoMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a VideoMetadata message.
-     * @function verify
-     * @memberof VideoMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    VideoMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.title != null && message.hasOwnProperty("title"))
-            if (!$util.isString(message.title))
-                return "title: string expected";
-        if (message.description != null && message.hasOwnProperty("description"))
-            if (!$util.isString(message.description))
-                return "description: string expected";
-        if (message.video != null && message.hasOwnProperty("video"))
-            if (!$util.isInteger(message.video))
-                return "video: integer expected";
-        if (message.thumbnailPhoto != null && message.hasOwnProperty("thumbnailPhoto"))
-            if (!$util.isInteger(message.thumbnailPhoto))
-                return "thumbnailPhoto: integer expected";
-        if (message.duration != null && message.hasOwnProperty("duration"))
-            if (!$util.isInteger(message.duration))
-                return "duration: integer expected";
-        if (message.mediaPixelHeight != null && message.hasOwnProperty("mediaPixelHeight"))
-            if (!$util.isInteger(message.mediaPixelHeight))
-                return "mediaPixelHeight: integer expected";
-        if (message.mediaPixelWidth != null && message.hasOwnProperty("mediaPixelWidth"))
-            if (!$util.isInteger(message.mediaPixelWidth))
-                return "mediaPixelWidth: integer expected";
-        if (message.mediaType != null && message.hasOwnProperty("mediaType")) {
-            var error = $root.MediaType.verify(message.mediaType);
-            if (error)
-                return "mediaType." + error;
-        }
-        if (message.language != null && message.hasOwnProperty("language"))
-            if (!$util.isString(message.language))
-                return "language: string expected";
-        if (message.license != null && message.hasOwnProperty("license")) {
-            var error = $root.License.verify(message.license);
-            if (error)
-                return "license." + error;
-        }
-        if (message.publishedBeforeJoystream != null && message.hasOwnProperty("publishedBeforeJoystream")) {
-            var error = $root.PublishedBeforeJoystream.verify(message.publishedBeforeJoystream);
-            if (error)
-                return "publishedBeforeJoystream." + error;
-        }
-        if (message.hasMarketing != null && message.hasOwnProperty("hasMarketing"))
-            if (typeof message.hasMarketing !== "boolean")
-                return "hasMarketing: boolean expected";
-        if (message.isPublic != null && message.hasOwnProperty("isPublic"))
-            if (typeof message.isPublic !== "boolean")
-                return "isPublic: boolean expected";
-        if (message.isExplicit != null && message.hasOwnProperty("isExplicit"))
-            if (typeof message.isExplicit !== "boolean")
-                return "isExplicit: boolean expected";
-        if (message.persons != null && message.hasOwnProperty("persons")) {
-            if (!Array.isArray(message.persons))
-                return "persons: array expected";
-            for (var i = 0; i < message.persons.length; ++i)
-                if (!$util.isInteger(message.persons[i]) && !(message.persons[i] && $util.isInteger(message.persons[i].low) && $util.isInteger(message.persons[i].high)))
-                    return "persons: integer|Long[] expected";
-        }
-        if (message.category != null && message.hasOwnProperty("category"))
-            if (!$util.isInteger(message.category) && !(message.category && $util.isInteger(message.category.low) && $util.isInteger(message.category.high)))
-                return "category: integer|Long expected";
-        return null;
-    };
-
-    /**
-     * Creates a VideoMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof VideoMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {VideoMetadata} VideoMetadata
-     */
-    VideoMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.VideoMetadata)
-            return object;
-        var message = new $root.VideoMetadata();
-        if (object.title != null)
-            message.title = String(object.title);
-        if (object.description != null)
-            message.description = String(object.description);
-        if (object.video != null)
-            message.video = object.video >>> 0;
-        if (object.thumbnailPhoto != null)
-            message.thumbnailPhoto = object.thumbnailPhoto >>> 0;
-        if (object.duration != null)
-            message.duration = object.duration >>> 0;
-        if (object.mediaPixelHeight != null)
-            message.mediaPixelHeight = object.mediaPixelHeight >>> 0;
-        if (object.mediaPixelWidth != null)
-            message.mediaPixelWidth = object.mediaPixelWidth >>> 0;
-        if (object.mediaType != null) {
-            if (typeof object.mediaType !== "object")
-                throw TypeError(".VideoMetadata.mediaType: object expected");
-            message.mediaType = $root.MediaType.fromObject(object.mediaType);
-        }
-        if (object.language != null)
-            message.language = String(object.language);
-        if (object.license != null) {
-            if (typeof object.license !== "object")
-                throw TypeError(".VideoMetadata.license: object expected");
-            message.license = $root.License.fromObject(object.license);
-        }
-        if (object.publishedBeforeJoystream != null) {
-            if (typeof object.publishedBeforeJoystream !== "object")
-                throw TypeError(".VideoMetadata.publishedBeforeJoystream: object expected");
-            message.publishedBeforeJoystream = $root.PublishedBeforeJoystream.fromObject(object.publishedBeforeJoystream);
-        }
-        if (object.hasMarketing != null)
-            message.hasMarketing = Boolean(object.hasMarketing);
-        if (object.isPublic != null)
-            message.isPublic = Boolean(object.isPublic);
-        if (object.isExplicit != null)
-            message.isExplicit = Boolean(object.isExplicit);
-        if (object.persons) {
-            if (!Array.isArray(object.persons))
-                throw TypeError(".VideoMetadata.persons: array expected");
-            message.persons = [];
-            for (var i = 0; i < object.persons.length; ++i)
-                if ($util.Long)
-                    (message.persons[i] = $util.Long.fromValue(object.persons[i])).unsigned = true;
-                else if (typeof object.persons[i] === "string")
-                    message.persons[i] = parseInt(object.persons[i], 10);
-                else if (typeof object.persons[i] === "number")
-                    message.persons[i] = object.persons[i];
-                else if (typeof object.persons[i] === "object")
-                    message.persons[i] = new $util.LongBits(object.persons[i].low >>> 0, object.persons[i].high >>> 0).toNumber(true);
-        }
-        if (object.category != null)
-            if ($util.Long)
-                (message.category = $util.Long.fromValue(object.category)).unsigned = true;
-            else if (typeof object.category === "string")
-                message.category = parseInt(object.category, 10);
-            else if (typeof object.category === "number")
-                message.category = object.category;
-            else if (typeof object.category === "object")
-                message.category = new $util.LongBits(object.category.low >>> 0, object.category.high >>> 0).toNumber(true);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a VideoMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof VideoMetadata
-     * @static
-     * @param {VideoMetadata} message VideoMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    VideoMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.arrays || options.defaults)
-            object.persons = [];
-        if (options.defaults) {
-            object.title = "";
-            object.description = "";
-            object.video = 0;
-            object.thumbnailPhoto = 0;
-            object.duration = 0;
-            object.mediaPixelHeight = 0;
-            object.mediaPixelWidth = 0;
-            object.mediaType = null;
-            object.language = "";
-            object.license = null;
-            object.publishedBeforeJoystream = null;
-            object.hasMarketing = false;
-            object.isPublic = false;
-            object.isExplicit = false;
-            if ($util.Long) {
-                var long = new $util.Long(0, 0, true);
-                object.category = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
-            } else
-                object.category = options.longs === String ? "0" : 0;
-        }
-        if (message.title != null && message.hasOwnProperty("title"))
-            object.title = message.title;
-        if (message.description != null && message.hasOwnProperty("description"))
-            object.description = message.description;
-        if (message.video != null && message.hasOwnProperty("video"))
-            object.video = message.video;
-        if (message.thumbnailPhoto != null && message.hasOwnProperty("thumbnailPhoto"))
-            object.thumbnailPhoto = message.thumbnailPhoto;
-        if (message.duration != null && message.hasOwnProperty("duration"))
-            object.duration = message.duration;
-        if (message.mediaPixelHeight != null && message.hasOwnProperty("mediaPixelHeight"))
-            object.mediaPixelHeight = message.mediaPixelHeight;
-        if (message.mediaPixelWidth != null && message.hasOwnProperty("mediaPixelWidth"))
-            object.mediaPixelWidth = message.mediaPixelWidth;
-        if (message.mediaType != null && message.hasOwnProperty("mediaType"))
-            object.mediaType = $root.MediaType.toObject(message.mediaType, options);
-        if (message.language != null && message.hasOwnProperty("language"))
-            object.language = message.language;
-        if (message.license != null && message.hasOwnProperty("license"))
-            object.license = $root.License.toObject(message.license, options);
-        if (message.publishedBeforeJoystream != null && message.hasOwnProperty("publishedBeforeJoystream"))
-            object.publishedBeforeJoystream = $root.PublishedBeforeJoystream.toObject(message.publishedBeforeJoystream, options);
-        if (message.hasMarketing != null && message.hasOwnProperty("hasMarketing"))
-            object.hasMarketing = message.hasMarketing;
-        if (message.isPublic != null && message.hasOwnProperty("isPublic"))
-            object.isPublic = message.isPublic;
-        if (message.isExplicit != null && message.hasOwnProperty("isExplicit"))
-            object.isExplicit = message.isExplicit;
-        if (message.persons && message.persons.length) {
-            object.persons = [];
-            for (var j = 0; j < message.persons.length; ++j)
-                if (typeof message.persons[j] === "number")
-                    object.persons[j] = options.longs === String ? String(message.persons[j]) : message.persons[j];
-                else
-                    object.persons[j] = options.longs === String ? $util.Long.prototype.toString.call(message.persons[j]) : options.longs === Number ? new $util.LongBits(message.persons[j].low >>> 0, message.persons[j].high >>> 0).toNumber(true) : message.persons[j];
-        }
-        if (message.category != null && message.hasOwnProperty("category"))
-            if (typeof message.category === "number")
-                object.category = options.longs === String ? String(message.category) : message.category;
-            else
-                object.category = options.longs === String ? $util.Long.prototype.toString.call(message.category) : options.longs === Number ? new $util.LongBits(message.category.low >>> 0, message.category.high >>> 0).toNumber(true) : message.category;
-        return object;
-    };
-
-    /**
-     * Converts this VideoMetadata to JSON.
-     * @function toJSON
-     * @memberof VideoMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    VideoMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return VideoMetadata;
-})();
-
-$root.VideoCategoryMetadata = (function() {
-
-    /**
-     * Properties of a VideoCategoryMetadata.
-     * @exports IVideoCategoryMetadata
-     * @interface IVideoCategoryMetadata
-     * @property {string|null} [name] VideoCategoryMetadata name
-     */
-
-    /**
-     * Constructs a new VideoCategoryMetadata.
-     * @exports VideoCategoryMetadata
-     * @classdesc Represents a VideoCategoryMetadata.
-     * @implements IVideoCategoryMetadata
-     * @constructor
-     * @param {IVideoCategoryMetadata=} [properties] Properties to set
-     */
-    function VideoCategoryMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * VideoCategoryMetadata name.
-     * @member {string} name
-     * @memberof VideoCategoryMetadata
-     * @instance
-     */
-    VideoCategoryMetadata.prototype.name = "";
-
-    /**
-     * Creates a new VideoCategoryMetadata instance using the specified properties.
-     * @function create
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {IVideoCategoryMetadata=} [properties] Properties to set
-     * @returns {VideoCategoryMetadata} VideoCategoryMetadata instance
-     */
-    VideoCategoryMetadata.create = function create(properties) {
-        return new VideoCategoryMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified VideoCategoryMetadata message. Does not implicitly {@link VideoCategoryMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {IVideoCategoryMetadata} message VideoCategoryMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    VideoCategoryMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.name != null && Object.hasOwnProperty.call(message, "name"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified VideoCategoryMetadata message, length delimited. Does not implicitly {@link VideoCategoryMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {IVideoCategoryMetadata} message VideoCategoryMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    VideoCategoryMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a VideoCategoryMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {VideoCategoryMetadata} VideoCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    VideoCategoryMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.VideoCategoryMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.name = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a VideoCategoryMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {VideoCategoryMetadata} VideoCategoryMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    VideoCategoryMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a VideoCategoryMetadata message.
-     * @function verify
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    VideoCategoryMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.name != null && message.hasOwnProperty("name"))
-            if (!$util.isString(message.name))
-                return "name: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a VideoCategoryMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {VideoCategoryMetadata} VideoCategoryMetadata
-     */
-    VideoCategoryMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.VideoCategoryMetadata)
-            return object;
-        var message = new $root.VideoCategoryMetadata();
-        if (object.name != null)
-            message.name = String(object.name);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a VideoCategoryMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof VideoCategoryMetadata
-     * @static
-     * @param {VideoCategoryMetadata} message VideoCategoryMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    VideoCategoryMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults)
-            object.name = "";
-        if (message.name != null && message.hasOwnProperty("name"))
-            object.name = message.name;
-        return object;
-    };
-
-    /**
-     * Converts this VideoCategoryMetadata to JSON.
-     * @function toJSON
-     * @memberof VideoCategoryMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    VideoCategoryMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return VideoCategoryMetadata;
-})();
-
-module.exports = $root;

+ 3 - 1
metadata-protobuf/package.json

@@ -42,7 +42,9 @@
     "@types/long": "^4.0.1",
     "i18n-iso-countries": "^6.8.0",
     "iso-639-1": "^2.1.9",
-    "protobufjs": "^6.11.2"
+    "protobufjs": "^6.11.2",
+    "iso-3166-2": "^1.0.0",
+    "@types/iso-3166-2": "^1.0.0"
   },
   "devDependencies": {
     "@types/chai": "^4.2.11",

+ 19 - 1
metadata-protobuf/proto/Storage.proto

@@ -23,8 +23,26 @@ message DistributionBucketOperatorMetadata {
   optional string extra = 3; // Additional information about the node / node operator
 }
 
+message GeographicalArea {
+  enum Continent {
+    AF = 1;
+    NA = 2;
+    OC = 3;
+    AN = 4;
+    AS = 5;
+    EU = 6;
+    SA = 7;
+  }
+  oneof code {
+    Continent continent = 1;
+    string country_code = 2; // ISO 3166-1 alpha-2 country code
+    string subdivision_code = 3; // ISO 3166-2 subdivision code
+  }
+}
+
 message DistributionBucketFamilyMetadata {
   optional string region = 1; // ID / name of the region covered by the distribution family (ie. us-east-1). Should be unique.
   optional string description = 2; // Additional, more specific description of the region
-  repeated GeoCoordiantes boundary = 3; // Geographical boundary of the region, defined as polygon through array of coordinates (providing [{}] will unset the current value)
+  repeated GeographicalArea areas = 3; // Standarized geographical areas covered by the family (providing [{}] will unset the current value)
+  repeated string latency_test_targets = 4; // List of targets (hosts/ips) best suited latency measurements for this family
 }

+ 4 - 0
metadata-protobuf/scripts/compile.ts

@@ -5,6 +5,10 @@ import fs from 'fs'
 
 const OUT_DIR = path.resolve(__dirname, '../compiled')
 
+if (!fs.existsSync(OUT_DIR)) {
+  fs.mkdirSync(OUT_DIR)
+}
+
 pbjs(
   ['--target', 'static-module', '-w', 'commonjs', '-o', `${OUT_DIR}/index.js`, '--force-long', 'proto/*.proto'],
   function (err) {

+ 6 - 0
metadata-protobuf/src/utils.ts

@@ -1,6 +1,7 @@
 import { AnyMessage, AnyMetadataClass, DecodedMetadataObject } from './types'
 import countries from 'i18n-iso-countries'
 import langs from 'iso-639-1'
+import subdivisions from 'iso-3166-2'
 
 export function isSet<T>(v: T | null | undefined): v is T {
   return v !== null && v !== undefined
@@ -42,3 +43,8 @@ export function isValidCountryCode(code: string): boolean {
 export function isValidLanguageCode(code: string): boolean {
   return langs.validate(code)
 }
+
+// According to ISO 3166-2 standard
+export function isValidSubdivisionCode(code: string): boolean {
+  return !!subdivisions.subdivision(code)
+}

+ 21 - 4
node/src/chain_spec/mod.rs

@@ -34,9 +34,10 @@ use node_runtime::{
     membership, wasm_binary_unwrap, AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig,
     ContentConfig, ContentWorkingGroupConfig, CouncilConfig, CouncilElectionConfig,
     DistributionWorkingGroupConfig, ElectionParameters, ForumConfig, GatewayWorkingGroupConfig,
-    GrandpaConfig, ImOnlineConfig, MembersConfig, Moment, OperationsWorkingGroupConfig,
-    ProposalsCodexConfig, SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig,
-    StorageWorkingGroupConfig, SudoConfig, SystemConfig, DAYS,
+    GrandpaConfig, ImOnlineConfig, MembersConfig, Moment, OperationsWorkingGroupAlphaConfig,
+    OperationsWorkingGroupBetaConfig, OperationsWorkingGroupGammaConfig, ProposalsCodexConfig,
+    SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig, StorageWorkingGroupConfig,
+    SudoConfig, SystemConfig, DAYS,
 };
 
 // Exported to be used by chain-spec-builder
@@ -314,7 +315,7 @@ pub fn testnet_genesis(
             worker_exit_rationale_text_constraint: default_text_constraint,
             worker_storage_size_constraint: default_storage_size_constraint,
         }),
-        working_group_Instance4: Some(OperationsWorkingGroupConfig {
+        working_group_Instance4: Some(OperationsWorkingGroupAlphaConfig {
             phantom: Default::default(),
             working_group_mint_capacity: 0,
             opening_human_readable_text_constraint: default_text_constraint,
@@ -338,6 +339,22 @@ pub fn testnet_genesis(
             worker_exit_rationale_text_constraint: default_text_constraint,
             worker_storage_size_constraint: default_storage_size_constraint,
         }),
+        working_group_Instance7: Some(OperationsWorkingGroupBetaConfig {
+            phantom: Default::default(),
+            working_group_mint_capacity: 0,
+            opening_human_readable_text_constraint: default_text_constraint,
+            worker_application_human_readable_text_constraint: default_text_constraint,
+            worker_exit_rationale_text_constraint: default_text_constraint,
+            worker_storage_size_constraint: default_storage_size_constraint,
+        }),
+        working_group_Instance8: Some(OperationsWorkingGroupGammaConfig {
+            phantom: Default::default(),
+            working_group_mint_capacity: 0,
+            opening_human_readable_text_constraint: default_text_constraint,
+            worker_application_human_readable_text_constraint: default_text_constraint,
+            worker_exit_rationale_text_constraint: default_text_constraint,
+            worker_storage_size_constraint: default_storage_size_constraint,
+        }),
         content: Some({
             ContentConfig {
                 next_curator_group_id: 1,

+ 13 - 22
pioneer/packages/joy-forum/src/ForumRoot.tsx

@@ -1,7 +1,6 @@
 import React, { useState, useEffect } from 'react';
 import { Link } from 'react-router-dom';
 import styled from 'styled-components';
-import { orderBy } from 'lodash';
 import BN from 'bn.js';
 
 import { Section } from '@polkadot/joy-utils/react/components';
@@ -63,36 +62,28 @@ const InnerRecentActivity: React.FC<RecentActivityProps> = ({ nextPostId, api })
       if (!nextPostId) return;
 
       const newId = (id: number | BN) => api.createType('PostId', id);
-      const apiCalls: Promise<Post>[] = [];
-      let id = newId(1);
+      let id = newId(nextPostId.toNumber() - 1);
 
-      while (nextPostId.gt(id)) {
-        apiCalls.push(api.query.forum.postById(id) as Promise<Post>);
-        id = newId(id.add(newId(1)));
-      }
+      const threadsIdsLookup = {} as Record<number, boolean>;
+      const recentUniquePosts = new Array<Post>();
 
-      const allPosts = await Promise.all(apiCalls);
-      const sortedPosts = orderBy(
-        allPosts,
-        [(x) => x.id.toNumber()],
-        ['desc']
-      );
+      while (id.gt(newId(0))) {
+        const post = await api.query.forum.postById(id) as Post;
 
-      const threadsIdsLookup = {} as Record<number, boolean>;
-      const postsWithUniqueThreads = sortedPosts.reduce((acc, post) => {
         const threadId = post.thread_id.toNumber();
 
-        if (threadsIdsLookup[threadId]) return acc;
+        id = newId(id.toNumber() - 1);
+
+        if (threadsIdsLookup[threadId]) continue;
 
         threadsIdsLookup[threadId] = true;
 
-        return [
-          ...acc,
-          post
-        ];
-      }, [] as Post[]);
+        recentUniquePosts.push(post);
 
-      const recentUniquePosts = postsWithUniqueThreads.slice(0, RecentActivityPostsCount);
+        if (recentUniquePosts.length === RecentActivityPostsCount) {
+          break;
+        }
+      }
 
       setRecentPosts(recentUniquePosts);
       setLoaded(true);

+ 78 - 14
pioneer/packages/joy-forum/src/ViewThread.tsx

@@ -5,7 +5,7 @@ import styled from 'styled-components';
 import { Table, Button, Label, Icon } from 'semantic-ui-react';
 import BN from 'bn.js';
 
-import { ThreadId } from '@joystream/types/common';
+import { PostId, ThreadId } from '@joystream/types/common';
 import { Category, Thread, Post } from '@joystream/types/forum';
 import { Pagination, RepliesPerPage, CategoryCrumbs, TimeAgoDate, usePagination, useQueryParam, ReplyIdxQueryParam, ReplyEditIdQueryParam } from './utils';
 import { ViewReply } from './ViewReply';
@@ -22,6 +22,7 @@ import MemberPreview from '@polkadot/joy-utils/react/components/MemberByAccountP
 import { formatDate } from '@polkadot/joy-utils/functions/date';
 import { NewReply, EditReply } from './EditReply';
 import { useApi } from '@polkadot/react-hooks';
+import { ApiPromise } from '@polkadot/api/promise';
 
 type ThreadTitleProps = {
   thread: Thread;
@@ -124,6 +125,77 @@ type ViewThreadProps = ApiProps & InnerViewThreadProps & {
   nextPostId?: ThreadId;
 };
 
+const POSTS_THREAD_MAP_CACHE_KEY = 'postsThreadMap';
+
+async function refreshPostsInThreadCache (nextPostId: PostId, api: ApiPromise) {
+  const newId = (id: number | BN) => api.createType('PostId', id);
+  const apiCalls: Promise<Post>[] = [];
+  let idToFetch = newId(1);
+
+  let postsToThread = getPostsIdsInThreadCache();
+  const nextThreadId = await api.query.forum.nextThreadId() as ThreadId;
+
+  if (postsToThread.size >= nextThreadId.toNumber()) { // invalid cache
+    postsToThread = new Map<number, number[]>();
+  }
+
+  if (postsToThread.size > 0) {
+    const lastPostIdInCache = Math.max(...Array.from(postsToThread.values()).flat());
+
+    idToFetch = newId(lastPostIdInCache + 1);
+    const lastPost = await api.query.forum.postById(lastPostIdInCache) as Post;
+
+    if (lastPost) {
+      const postsInThread = postsToThread.get(lastPost.thread_id.toNumber());
+
+      if (!postsInThread || !postsInThread.includes(lastPostIdInCache)) { // cache doesn't match the data in chain
+        postsToThread = new Map<number, number[]>();
+      }
+    } else {
+      postsToThread = new Map<number, number[]>();
+    }
+  }
+
+  const lastPostId = nextPostId.sub(new BN(1));
+
+  while (lastPostId.gte(idToFetch)) {
+    apiCalls.push(api.query.forum.postById(idToFetch) as Promise<Post>);
+    idToFetch = newId(idToFetch.add(newId(1)));
+  }
+
+  const newPosts = await Promise.all<Post>(apiCalls);
+
+  const newPostsToThread = new Map<number, number[]>();
+
+  newPosts.forEach((newPost) => {
+    const previousNewPostIds = newPostsToThread.get(newPost.thread_id.toNumber()) ?? [];
+
+    newPostsToThread.set(newPost.thread_id.toNumber(), [...previousNewPostIds, newPost.id.toNumber()]);
+  });
+
+  if (postsToThread.size > 0) {
+    newPostsToThread.forEach((postIds, threadId) => {
+      const existingPostIds = postsToThread.get(threadId) ?? [];
+
+      postsToThread.set(threadId, [...existingPostIds, ...postIds]);
+    });
+  } else {
+    postsToThread = newPostsToThread;
+  }
+
+  localStorage.setItem(POSTS_THREAD_MAP_CACHE_KEY, JSON.stringify([...postsToThread]));
+}
+
+function getPostsIdsInThreadCache (): Map<number, number[]> {
+  const serializedMap = localStorage.getItem(POSTS_THREAD_MAP_CACHE_KEY);
+
+  if (!serializedMap) {
+    return new Map<number, number[]>();
+  }
+
+  return new Map<number, number[]>(JSON.parse(serializedMap));
+}
+
 function InnerViewThread (props: ViewThreadProps) {
   const [showModerateForm, setShowModerateForm] = useState(false);
   const [displayedPosts, setDisplayedPosts] = useState<Post[]>([]);
@@ -154,20 +226,12 @@ function InnerViewThread (props: ViewThreadProps) {
     const loadPosts = async () => {
       if (!nextPostId || totalPostsInThread === 0 || thread.isEmpty) return;
 
-      const newId = (id: number | BN) => api.createType('PostId', id);
-      const apiCalls: Promise<Post>[] = [];
-      let id = newId(1);
-
-      while (nextPostId.gt(id)) {
-        apiCalls.push(api.query.forum.postById(id) as Promise<Post>);
-        id = newId(id.add(newId(1)));
-      }
+      await refreshPostsInThreadCache(nextPostId, api);
+      const mapPostToThread = getPostsIdsInThreadCache();
+      const postIdsInThread = mapPostToThread.get(thread.id.toNumber()) as number[];
+      const postsInThisThread = await Promise.all(postIdsInThread
+        ? postIdsInThread.map((postId: number) => api.query.forum.postById(postId)) : []) as Post[];
 
-      const allPosts = await Promise.all<Post>(apiCalls);
-      const postsInThisThread = allPosts.filter((item) =>
-        !item.isEmpty &&
-        item.thread_id.eq(thread.id)
-      );
       const sortedPosts = orderBy(
         postsInThisThread,
         [(x) => x.nr_in_thread.toNumber()],

+ 3 - 7
pioneer/packages/joy-utils/src/transport/proposals.ts

@@ -187,14 +187,10 @@ export default class ProposalsTransport extends BaseTransport {
   }
 
   async voteByProposalAndMember (proposalId: ProposalId, voterId: MemberId): Promise<VoteKind | null> {
-    const votesEntries = await this.api.query.proposalsEngine.voteExistsByProposalByVoter.entries(proposalId);
-    const voteEntry = votesEntries.find((voteEntry) => {
-      const memberId = voteEntry[0].args[1] as MemberId;
+    const vote = (await this.proposalsEngine.voteExistsByProposalByVoter(proposalId, voterId)) as VoteKind;
+    const hasVoted = (await this.api.query.proposalsEngine.voteExistsByProposalByVoter.size(proposalId, voterId)).toNumber();
 
-      return memberId.eq(voterId);
-    });
-
-    return voteEntry ? voteEntry[1] as VoteKind : null;
+    return hasVoted ? vote : null;
   }
 
   async votes (proposalId: ProposalId): Promise<ProposalVotes> {

+ 15 - 11
query-node/mappings/content/utils.ts

@@ -138,14 +138,14 @@ export async function processVideoMetadata(
 function findAssetByIndex(assets: typeof Asset[], index: number, name?: string): typeof Asset | null {
   if (assets[index]) {
     return assets[index]
-  } else {
-    invalidMetadata(`Invalid${name ? ' ' + name : ''} asset index`, {
-      numberOfAssets: assets.length,
-      requestedAssetIndex: index,
-    })
-
-    return null
   }
+
+  invalidMetadata(`Invalid${name ? ' ' + name : ''} asset index`, {
+    numberOfAssets: assets.length,
+    requestedAssetIndex: index,
+  })
+
+  return null
 }
 
 async function processVideoMediaEncoding(
@@ -279,7 +279,9 @@ async function processNewAssets(ctx: EventContext & StoreContext, assets: NewAss
       resultAsset.urls = JSON.stringify(assetUrls.map((u) => u.toString()))
       return resultAsset
     })
-  } else if (assets.isUpload) {
+  }
+
+  if (assets.isUpload) {
     const assetsUploaded = assets.asUpload.object_creation_list.length
     // FIXME: Ideally the runtime would provide object ids in ChannelCreated/VideoCreated/ChannelUpdated(...) events
     const objects = await getMostRecentlyCreatedDataObjects(ctx.store, assetsUploaded)
@@ -288,9 +290,9 @@ async function processNewAssets(ctx: EventContext & StoreContext, assets: NewAss
       resultAsset.dataObjectId = o.id
       return resultAsset
     })
-  } else {
-    unexpectedData('Unrecognized assets type', assets.type)
   }
+
+  unexpectedData('Unrecognized assets type', assets.type)
 }
 
 function extractVideoSize(assets: NewAssets | undefined, assetIndex: number | null | undefined): number | undefined {
@@ -500,7 +502,9 @@ export async function unsetAssetRelations(store: DatabaseManager, dataObject: St
       channelId: channel.id.toString(),
       dataObjectId: dataObject.id,
     })
-  } else if (video) {
+  }
+
+  if (video) {
     videoAssets.forEach((assetName) => {
       if (video[assetName] && (video[assetName] as AssetJoystreamStorage).dataObjectId === dataObject.id) {
         video[assetName] = new AssetNone()

+ 1 - 1
query-node/mappings/storage/index.ts

@@ -171,7 +171,7 @@ async function getDistributionBucketFamilyWithMetadata(
 ): Promise<DistributionBucketFamily> {
   const family = await store.get(DistributionBucketFamily, {
     where: { id },
-    relations: ['metadata', 'metadata.boundary'],
+    relations: ['metadata', 'metadata.areas'],
   })
   if (!family) {
     throw new Error(`DistributionBucketFamily not found by id: ${id}`)

+ 65 - 16
query-node/mappings/storage/metadata.ts

@@ -5,16 +5,32 @@ import {
   StorageBucketOperatorMetadata,
   GeoCoordinates,
   NodeLocationMetadata,
+  Continent,
+  GeographicalAreaContinent,
+  GeographicalAreaCountry,
+  GeographicalAreaSubdivistion,
+  DistributionBucketFamilyGeographicArea,
 } from 'query-node/dist/model'
-import { deserializeMetadata } from '../common'
+import { deserializeMetadata, invalidMetadata } from '../common'
 import { Bytes } from '@polkadot/types'
 import {
   DistributionBucketOperatorMetadata as DistributionBucketOperatorMetadataProto,
   StorageBucketOperatorMetadata as StorageBucketOperatorMetadataProto,
   DistributionBucketFamilyMetadata as DistributionBucketFamilyMetadataProto,
   INodeLocationMetadata,
+  GeographicalArea as GeographicalAreaProto,
 } from '@joystream/metadata-protobuf'
-import { isSet, isEmptyObject, isValidCountryCode } from '@joystream/metadata-protobuf/utils'
+import { isSet, isEmptyObject, isValidCountryCode, isValidSubdivisionCode } from '@joystream/metadata-protobuf/utils'
+
+const protobufContinentToGraphlContinent: { [key in GeographicalAreaProto.Continent]: Continent } = {
+  [GeographicalAreaProto.Continent.AF]: Continent.AF,
+  [GeographicalAreaProto.Continent.AN]: Continent.AN,
+  [GeographicalAreaProto.Continent.AS]: Continent.AS,
+  [GeographicalAreaProto.Continent.EU]: Continent.EU,
+  [GeographicalAreaProto.Continent.NA]: Continent.NA,
+  [GeographicalAreaProto.Continent.OC]: Continent.OC,
+  [GeographicalAreaProto.Continent.SA]: Continent.SA,
+}
 
 async function processNodeLocationMetadata(
   store: DatabaseManager,
@@ -118,24 +134,57 @@ export async function processDistributionBucketFamilyMetadata(
   if (isSet(meta.description)) {
     metadataEntity.description = meta.description || (null as any)
   }
+  if (isSet(meta.latencyTestTargets)) {
+    metadataEntity.latencyTestTargets = meta.latencyTestTargets
+  }
 
   await store.save<DistributionBucketOperatorMetadata>(metadataEntity)
 
-  // Update boundary after metadata is saved (since we need an id to reference)
-  if (isSet(meta.boundary)) {
-    await Promise.all((metadataEntity.boundary || []).map((coords) => store.remove<GeoCoordinates>(coords)))
+  // Update areas after metadata is saved (since we need an id to reference)
+  if (isSet(meta.areas)) {
+    // Drop current areas
+    await Promise.all(metadataEntity.areas?.map((a) => store.remove<DistributionBucketFamilyGeographicArea>(a)) || [])
+    // Save new areas
     await Promise.all(
-      meta.boundary
-        .filter((c) => !isEmptyObject(c))
-        .map(({ latitude, longitude }) =>
-          store.save<GeoCoordinates>(
-            new GeoCoordinates({
-              latitude: latitude || 0,
-              longitude: longitude || 0,
-              boundarySourceBucketFamilyMeta: metadataEntity,
-            })
-          )
-        )
+      meta.areas
+        .filter((a) => !isEmptyObject(a))
+        .map(async (a) => {
+          const area = new DistributionBucketFamilyGeographicArea({
+            distributionBucketFamilyMetadata: metadataEntity,
+          })
+
+          if (a.continent) {
+            const continent = new GeographicalAreaContinent()
+            continent.code = protobufContinentToGraphlContinent[a.continent]
+            if (!continent.code) {
+              return invalidMetadata(`Unrecognized continent enum variant: ${a.continent}`)
+            }
+            area.id = `${metadataEntity.id}-C-${continent.code}`
+            area.area = continent
+          }
+
+          if (a.countryCode) {
+            if (!isValidCountryCode(a.countryCode)) {
+              return invalidMetadata(`Invalid country code: ${a.countryCode}`)
+            }
+            const country = new GeographicalAreaCountry()
+            country.code = a.countryCode
+            area.id = `${metadataEntity.id}-c-${country.code}`
+            area.area = country
+          }
+
+          if (a.subdivisionCode) {
+            if (!isValidSubdivisionCode(a.subdivisionCode)) {
+              return invalidMetadata(`Invalid subdivision code: ${a.subdivisionCode}`)
+            }
+            const subdivision = new GeographicalAreaSubdivistion()
+            subdivision.code = a.subdivisionCode
+            area.id = `${metadataEntity.id}-s-${subdivision.code}`
+            area.area = subdivision
+          }
+
+          await store.save<DistributionBucketFamilyGeographicArea>(area)
+        })
     )
   }
 

+ 4 - 1
query-node/mappings/workingGroup.ts

@@ -96,9 +96,12 @@ export async function workingGroup_TerminatedLeader({ event, store }: EventConte
 function getWorkerType(event: SubstrateEvent): WorkerType | null {
   if (event.section === 'storageWorkingGroup') {
     return WorkerType.STORAGE
-  } else if (event.section === 'gatewayWorkingGroup') {
+  }
+
+  if (event.section === 'gatewayWorkingGroup') {
     return WorkerType.GATEWAY
   }
+
   return null
 }
 

+ 41 - 4
query-node/schemas/storage.graphql

@@ -42,11 +42,34 @@ union StorageBucketOperatorStatus = StorageBucketOperatorStatusMissing | Storage
 type GeoCoordinates @entity {
   latitude: Float!
   longitude: Float!
+}
+
+enum Continent {
+  AF
+  NA
+  OC
+  AN
+  AS
+  EU
+  SA
+}
+
+type GeographicalAreaContinent @variant {
+  code: Continent
+}
+
+type GeographicalAreaCountry @variant {
+  "ISO 3166-1 alpha-2 country code"
+  code: String
+}
 
-  "Optional DistributionBucketFamilyMetadata reference in case the coordinates are part of a region boundary"
-  boundarySourceBucketFamilyMeta: DistributionBucketFamilyMetadata
+type GeographicalAreaSubdivistion @variant {
+  "ISO 3166-2 subdivision code"
+  code: String
 }
 
+union GeographicalArea = GeographicalAreaContinent | GeographicalAreaCountry | GeographicalAreaSubdivistion
+
 type NodeLocationMetadata @entity {
   "ISO 3166-1 alpha-2 country code (2 letters)"
   countryCode: String
@@ -185,6 +208,17 @@ type StorageDataObject @entity {
   ipfsHash: String!
 }
 
+type DistributionBucketFamilyGeographicArea @entity {
+  "{metadataId}-{(C|c|s)}-{code}"
+  id: ID!
+
+  "Geographical area (continent / country / subdivision)"
+  area: GeographicalArea!
+
+  "Related distribution bucket family metadata"
+  distributionBucketFamilyMetadata: DistributionBucketFamilyMetadata!
+}
+
 type DistributionBucketFamilyMetadata @entity {
   "Name of the geographical region covered by the family (ie.: us-east-1)"
   region: String
@@ -192,8 +226,11 @@ type DistributionBucketFamilyMetadata @entity {
   "Optional, more specific description of the region covered by the family"
   description: String
 
-  "Optional region boundary as geocoordiantes polygon"
-  boundary: [GeoCoordinates!] @derivedFrom(field: "boundarySourceBucketFamilyMeta")
+  "Geographical areas covered by the family"
+  areas: [DistributionBucketFamilyGeographicArea!] @derivedFrom(field: "distributionBucketFamilyMetadata")
+
+  "List of targets (hosts/ips) best suited latency measurements for the family"
+  latencyTestTargets: [String!]
 }
 
 type DistributionBucketOperatorMetadata @entity {

+ 8 - 2
runtime-modules/common/src/working_group.rs

@@ -22,11 +22,17 @@ pub enum WorkingGroup {
     Content = 3isize,
 
     /// Operations working group: working_group::Instance4.
-    Operations = 4isize,
+    OperationsAlpha = 4isize,
 
     /// Gateway working group: working_group::Instance5.
     Gateway = 5isize,
 
-    /// Distribution working group: working_group::Instance4.
+    /// Distribution working group: working_group::Instance6.
     Distribution = 6isize,
+
+    /// Operations working group: working_group::Instance7.
+    OperationsBeta = 7isize,
+
+    /// Operations working group: working_group::Instance8.
+    OperationsGamma = 8isize,
 }

+ 1 - 1
runtime-modules/content/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-content'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 6 - 13
runtime-modules/content/src/lib.rs

@@ -127,7 +127,7 @@ pub enum ChannelOwner<MemberId, CuratorGroupId> {
 // simplification type
 pub(crate) type ActorToChannelOwnerResult<T> = Result<
     ChannelOwner<
-        <T as membership::Trait>::MemberId,
+        <T as common::MembershipTypes>::MemberId,
         <T as ContentActorAuthenticator>::CuratorGroupId,
     >,
     Error<T>,
@@ -185,7 +185,7 @@ pub struct ChannelRecord<MemberId, CuratorGroupId, AccountId> {
 
 // Channel alias type for simplification.
 pub type Channel<T> = ChannelRecord<
-    <T as membership::Trait>::MemberId,
+    <T as common::MembershipTypes>::MemberId,
     <T as ContentActorAuthenticator>::CuratorGroupId,
     <T as frame_system::Trait>::AccountId,
 >;
@@ -209,7 +209,7 @@ pub struct ChannelOwnershipTransferRequestRecord<
 // ChannelOwnershipTransferRequest type alias for simplification.
 pub type ChannelOwnershipTransferRequest<T> = ChannelOwnershipTransferRequestRecord<
     <T as storage::Trait>::ChannelId,
-    <T as membership::Trait>::MemberId,
+    <T as common::MembershipTypes>::MemberId,
     <T as ContentActorAuthenticator>::CuratorGroupId,
     BalanceOf<T>,
     <T as frame_system::Trait>::AccountId,
@@ -1446,17 +1446,10 @@ impl<T: Trait> Module<T> {
         match actor {
             // Lead should use their member or curator role to create channels
             ContentActor::Lead => Err(Error::<T>::ActorCannotOwnChannel),
-            ContentActor::Curator(
-                curator_group_id,
-                _curator_id
-            ) => {
+            ContentActor::Curator(curator_group_id, _curator_id) => {
                 Ok(ChannelOwner::CuratorGroup(*curator_group_id))
             }
-            ContentActor::Member(member_id) => {
-                Ok(ChannelOwner::Member(*member_id))
-            }
-            // TODO:
-            // ContentActor::Dao(id) => Ok(ChannelOwner::Dao(id)),
+            ContentActor::Member(member_id) => Ok(ChannelOwner::Member(*member_id)),
         }
     }
 
@@ -1477,7 +1470,7 @@ decl_event!(
         ContentActor = ContentActor<
             <T as ContentActorAuthenticator>::CuratorGroupId,
             <T as ContentActorAuthenticator>::CuratorId,
-            <T as membership::Trait>::MemberId,
+            <T as common::MembershipTypes>::MemberId,
         >,
         CuratorGroupId = <T as ContentActorAuthenticator>::CuratorGroupId,
         CuratorId = <T as ContentActorAuthenticator>::CuratorId,

+ 7 - 41
runtime-modules/content/src/permissions/mod.rs

@@ -11,7 +11,6 @@ use frame_support::{ensure, Parameter};
 pub use serde::{Deserialize, Serialize};
 use sp_arithmetic::traits::BaseArithmetic;
 use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
-// use frame_system::ensure_root;
 
 /// Model of authentication manager.
 pub trait ContentActorAuthenticator: frame_system::Trait + membership::Trait {
@@ -104,26 +103,18 @@ pub fn ensure_actor_authorized_to_create_channel<T: Trait>(
 ) -> DispatchResult {
     match actor {
         // Lead should use their member or curator role to create or update channel assets.
-        ContentActor::Lead => {
-            Err(Error::<T>::ActorCannotOwnChannel.into())
-        }
+        ContentActor::Lead => Err(Error::<T>::ActorCannotOwnChannel.into()),
         ContentActor::Curator(curator_group_id, curator_id) => {
             let sender = ensure_signed(origin)?;
 
             // Authorize curator, performing all checks to ensure curator can act
-            CuratorGroup::<T>::perform_curator_in_group_auth(
-                curator_id,
-                curator_group_id,
-                &sender,
-            )
+            CuratorGroup::<T>::perform_curator_in_group_auth(curator_id, curator_group_id, &sender)
         }
         ContentActor::Member(member_id) => {
             let sender = ensure_signed(origin)?;
 
             ensure_member_auth_success::<T>(member_id, &sender)
         }
-        // TODO:
-        // ContentActor::Dao(_daoId) => ...,
     }
 }
 
@@ -176,8 +167,6 @@ pub fn ensure_actor_authorized_to_update_channel<T: Trait>(
 
             Ok(())
         }
-        // TODO:
-        // ContentActor::Dao(_daoId) => ...,
     }
 }
 
@@ -206,7 +195,7 @@ pub fn ensure_actor_authorized_to_censor<T: Trait>(
         ContentActor::Lead => {
             let sender = ensure_signed(origin)?;
             ensure_lead_auth_success::<T>(&sender)
-        },
+        }
         ContentActor::Curator(curator_group_id, curator_id) => {
             let sender = ensure_signed(origin)?;
 
@@ -223,13 +212,11 @@ pub fn ensure_actor_authorized_to_censor<T: Trait>(
             } else {
                 Ok(())
             }
-        },
+        }
         ContentActor::Member(_) => {
             // Members cannot censore channels!
             Err(Error::<T>::ActorNotAuthorized.into())
         }
-        // TODO:
-        // ContentActor::Dao(_daoId) => ...,
     }
 }
 
@@ -242,40 +229,20 @@ pub fn ensure_actor_authorized_to_manage_categories<T: Trait>(
         ContentActor::Lead => {
             let sender = ensure_signed(origin)?;
             ensure_lead_auth_success::<T>(&sender)
-        },
+        }
         ContentActor::Curator(curator_group_id, curator_id) => {
             let sender = ensure_signed(origin)?;
 
             // Authorize curator, performing all checks to ensure curator can act
-            CuratorGroup::<T>::perform_curator_in_group_auth(
-                curator_id,
-                curator_group_id,
-                &sender,
-            )
-        },
+            CuratorGroup::<T>::perform_curator_in_group_auth(curator_id, curator_group_id, &sender)
+        }
         ContentActor::Member(_) => {
             // Members cannot censore channels!
             Err(Error::<T>::ActorNotAuthorized.into())
         }
-        // TODO:
-        // ContentActor::Dao(_daoId) => ...,
     }
 }
 
-// pub fn ensure_actor_authorized_to_delete_stale_assets<T: Trait>(
-//     origin: T::Origin,
-//     actor: &ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-// ) -> DispatchResult {
-//     // Only Lead and (sudo) can delete assets no longer associated with a channel or person.
-//     if let ContentActor::Lead = actor {
-//         let sender = ensure_signed(origin)?;
-//         ensure_lead_auth_success::<T>(&sender)
-//     } else {
-//         ensure_root(origin)?;
-//         Ok(())
-//     }
-// }
-
 /// Enum, representing all possible `Actor`s
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Copy, Debug)]
@@ -287,7 +254,6 @@ pub enum ContentActor<
     Curator(CuratorGroupId, CuratorId),
     Member(MemberId),
     Lead,
-    // Dao,
 }
 
 impl<

+ 0 - 2
runtime-modules/content/src/tests/mock.rs

@@ -153,10 +153,8 @@ parameter_types! {
 
 impl membership::Trait for Test {
     type Event = MetaEvent;
-    type MemberId = u64;
     type PaidTermId = u64;
     type SubscriptionId = u64;
-    type ActorId = u64;
     type ScreenedMemberMaxInitialBalance = ();
 }
 

+ 1 - 1
runtime-modules/forum/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-forum'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 1 - 1
runtime-modules/governance/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-governance'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 5 - 2
runtime-modules/governance/src/mock.rs

@@ -76,12 +76,15 @@ parameter_types! {
     pub const ScreenedMemberMaxInitialBalance: u64 = 500;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
 impl membership::Trait for Test {
     type Event = ();
-    type MemberId = u64;
     type SubscriptionId = u32;
     type PaidTermId = u32;
-    type ActorId = u32;
     type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
 }
 impl minting::Trait for Test {

+ 1 - 1
runtime-modules/hiring/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-hiring'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 1 - 1
runtime-modules/membership/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-membership'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 22 - 40
runtime-modules/membership/src/lib.rs

@@ -23,18 +23,11 @@ use sp_std::vec;
 use sp_std::vec::Vec;
 
 use common::currency::{BalanceOf, GovernanceCurrency};
-pub trait Trait: frame_system::Trait + GovernanceCurrency + pallet_timestamp::Trait {
+pub trait Trait:
+    frame_system::Trait + GovernanceCurrency + pallet_timestamp::Trait + common::MembershipTypes
+{
     type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
 
-    type MemberId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq;
-
     type PaidTermId: Parameter
         + Member
         + BaseArithmetic
@@ -53,17 +46,6 @@ pub trait Trait: frame_system::Trait + GovernanceCurrency + pallet_timestamp::Tr
         + MaybeSerialize
         + PartialEq;
 
-    /// Describes the common type for the working group members (workers).
-    type ActorId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq
-        + Ord;
-
     /// The maximum amount of initial funds that may be endowed to new members added by
     /// screening authority. If set to zero, no initial balance can be given.
     type ScreenedMemberMaxInitialBalance: Get<BalanceOf<Self>>;
@@ -246,13 +228,13 @@ decl_storage! {
 decl_event! {
     pub enum Event<T> where
       <T as frame_system::Trait>::AccountId,
-      <T as Trait>::MemberId,
+      <T as common::MembershipTypes>::MemberId,
       <T as Trait>::PaidTermId,
     {
         MemberRegistered(MemberId, AccountId, EntryMethod<PaidTermId, AccountId>),
-        MemberUpdatedAboutText(MemberId),
-        MemberUpdatedAvatar(MemberId),
-        MemberUpdatedHandle(MemberId),
+        MemberUpdatedAboutText(MemberId, Vec<u8>),
+        MemberUpdatedAvatar(MemberId, Vec<u8>),
+        MemberUpdatedHandle(MemberId, Vec<u8>),
         MemberSetRootAccount(MemberId, AccountId),
         MemberSetControllerAccount(MemberId, AccountId),
     }
@@ -312,7 +294,7 @@ decl_module! {
 
             ensure!(membership.controller_account == sender, Error::<T>::ControllerAccountRequired);
 
-            Self::_change_member_about_text(member_id, &text)?;
+            Self::_change_member_about_text(member_id, text)?;
         }
 
         /// Change member's avatar
@@ -324,7 +306,7 @@ decl_module! {
 
             ensure!(membership.controller_account == sender, Error::<T>::ControllerAccountRequired);
 
-            Self::_change_member_avatar(member_id, &uri)?;
+            Self::_change_member_avatar(member_id, uri)?;
         }
 
         /// Change member's handle. Will ensure new handle is unique and old one will be available
@@ -356,10 +338,10 @@ decl_module! {
             ensure!(membership.controller_account == sender, Error::<T>::ControllerAccountRequired);
 
             if let Some(uri) = avatar_uri {
-                Self::_change_member_avatar(member_id, &uri)?;
+                Self::_change_member_avatar(member_id, uri)?;
             }
             if let Some(about) = about {
-                Self::_change_member_about_text(member_id, &about)?;
+                Self::_change_member_about_text(member_id, about)?;
             }
             if let Some(handle) = handle {
                 Self::_change_member_handle(member_id, handle)?;
@@ -588,8 +570,8 @@ impl<T: Trait> Module<T> {
         Ok(())
     }
 
-    fn validate_text(text: &[u8]) -> Vec<u8> {
-        let mut text = text.to_owned();
+    fn validate_text(text: Vec<u8>) -> Vec<u8> {
+        let mut text = text;
         text.truncate(Self::max_about_text_length() as usize);
         text
     }
@@ -612,7 +594,7 @@ impl<T: Trait> Module<T> {
         let handle = handle.ok_or(Error::<T>::HandleMustBeProvidedDuringRegistration)?;
         Self::validate_handle(&handle)?;
 
-        let about = Self::validate_text(&about.unwrap_or_default());
+        let about = Self::validate_text(about.unwrap_or_default());
         let avatar_uri = avatar_uri.unwrap_or_default();
         Self::validate_avatar(&avatar_uri)?;
 
@@ -662,20 +644,20 @@ impl<T: Trait> Module<T> {
         Ok(new_member_id)
     }
 
-    fn _change_member_about_text(id: T::MemberId, text: &[u8]) -> DispatchResult {
+    fn _change_member_about_text(id: T::MemberId, text: Vec<u8>) -> DispatchResult {
         let mut membership = Self::ensure_membership(id)?;
         let text = Self::validate_text(text);
-        membership.about = text;
-        Self::deposit_event(RawEvent::MemberUpdatedAboutText(id));
+        membership.about = text.clone();
+        Self::deposit_event(RawEvent::MemberUpdatedAboutText(id, text));
         <MembershipById<T>>::insert(id, membership);
         Ok(())
     }
 
-    fn _change_member_avatar(id: T::MemberId, uri: &[u8]) -> DispatchResult {
+    fn _change_member_avatar(id: T::MemberId, uri: Vec<u8>) -> DispatchResult {
         let mut membership = Self::ensure_membership(id)?;
-        Self::validate_avatar(uri)?;
+        Self::validate_avatar(&uri)?;
         membership.avatar_uri = uri.to_owned();
-        Self::deposit_event(RawEvent::MemberUpdatedAvatar(id));
+        Self::deposit_event(RawEvent::MemberUpdatedAvatar(id, uri));
         <MembershipById<T>>::insert(id, membership);
         Ok(())
     }
@@ -686,8 +668,8 @@ impl<T: Trait> Module<T> {
         Self::ensure_unique_handle(&handle)?;
         <MemberIdByHandle<T>>::remove(&membership.handle);
         <MemberIdByHandle<T>>::insert(handle.clone(), id);
-        membership.handle = handle;
-        Self::deposit_event(RawEvent::MemberUpdatedHandle(id));
+        membership.handle = handle.clone();
+        Self::deposit_event(RawEvent::MemberUpdatedHandle(id, handle));
         <MembershipById<T>>::insert(id, membership);
         Ok(())
     }

+ 5 - 2
runtime-modules/membership/src/mock.rs

@@ -86,12 +86,15 @@ parameter_types! {
     pub const ScreenedMemberMaxInitialBalance: u64 = 500;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
 impl Trait for Test {
     type Event = ();
-    type MemberId = u64;
     type PaidTermId = u32;
     type SubscriptionId = u32;
-    type ActorId = u32;
     type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
 }
 

+ 1 - 1
runtime-modules/memo/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-memo'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 1 - 1
runtime-modules/proposals/codex/src/lib.rs

@@ -181,7 +181,7 @@ pub type NegativeImbalance<T> = <<T as stake::Trait>::Currency as Currency<
     <T as frame_system::Trait>::AccountId,
 >>::NegativeImbalance;
 
-type MemberId<T> = <T as membership::Trait>::MemberId;
+type MemberId<T> = <T as common::MembershipTypes>::MemberId;
 
 decl_error! {
     /// Codex module predefined errors

+ 5 - 2
runtime-modules/proposals/codex/src/tests/mock.rs

@@ -50,12 +50,15 @@ parameter_types! {
     pub const ScreenedMemberMaxInitialBalance: u64 = 500;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
 impl membership::Trait for Test {
     type Event = ();
-    type MemberId = u64;
     type PaidTermId = u64;
     type SubscriptionId = u64;
-    type ActorId = u64;
     type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
 }
 

+ 1 - 1
runtime-modules/proposals/discussion/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-proposals-discussion'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 1 - 1
runtime-modules/proposals/discussion/src/lib.rs

@@ -59,7 +59,7 @@ use sp_std::vec::Vec;
 use common::origin::ActorOriginValidator;
 use types::{DiscussionPost, DiscussionThread, ThreadCounter};
 
-type MemberId<T> = <T as membership::Trait>::MemberId;
+type MemberId<T> = <T as common::MembershipTypes>::MemberId;
 
 decl_event!(
     /// Proposals engine events

+ 5 - 2
runtime-modules/proposals/discussion/src/tests/mock.rs

@@ -77,12 +77,15 @@ parameter_types! {
     pub const ScreenedMemberMaxInitialBalance: u64 = 500;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
 impl membership::Trait for Test {
     type Event = TestEvent;
-    type MemberId = u64;
     type PaidTermId = u64;
     type SubscriptionId = u64;
-    type ActorId = u64;
     type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
 }
 

+ 1 - 1
runtime-modules/proposals/engine/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-proposals-engine'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 1 - 1
runtime-modules/proposals/engine/src/lib.rs

@@ -143,7 +143,7 @@ use sp_std::vec::Vec;
 
 use common::origin::ActorOriginValidator;
 
-type MemberId<T> = <T as membership::Trait>::MemberId;
+type MemberId<T> = <T as common::MembershipTypes>::MemberId;
 
 /// Proposals engine trait.
 pub trait Trait:

+ 5 - 2
runtime-modules/proposals/engine/src/tests/mock/mod.rs

@@ -90,12 +90,15 @@ parameter_types! {
     pub const ScreenedMemberMaxInitialBalance: u64 = 500;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
 impl membership::Trait for Test {
     type Event = TestEvent;
-    type MemberId = u64;
     type PaidTermId = u64;
     type SubscriptionId = u64;
-    type ActorId = u64;
     type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
 }
 

+ 1 - 1
runtime-modules/recurring-reward/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-recurring-reward'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 1 - 1
runtime-modules/stake/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-stake'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 2 - 2
runtime-modules/storage/src/lib.rs

@@ -452,10 +452,10 @@ pub type Cid = Vec<u8>;
 type Balances<T> = balances::Module<T>;
 
 /// Alias for the member id.
-pub type MemberId<T> = <T as membership::Trait>::MemberId;
+pub type MemberId<T> = <T as common::MembershipTypes>::MemberId;
 
 /// Type identifier for worker role, which must be same as membership actor identifier
-pub type WorkerId<T> = <T as membership::Trait>::ActorId;
+pub type WorkerId<T> = <T as common::MembershipTypes>::ActorId;
 
 /// Balance alias for `balances` module.
 pub type BalanceOf<T> = <T as balances::Trait>::Balance;

+ 5 - 2
runtime-modules/storage/src/tests/mocks.rs

@@ -189,12 +189,15 @@ parameter_types! {
     pub const ScreenedMemberMaxInitialBalance: u64 = 5000;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
 impl membership::Trait for Test {
     type Event = TestEvent;
-    type MemberId = u64;
     type PaidTermId = u64;
     type SubscriptionId = u64;
-    type ActorId = u64;
     type ScreenedMemberMaxInitialBalance = ();
 }
 

+ 1 - 1
runtime-modules/token-minting/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-token-mint'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 1 - 1
runtime-modules/working-group/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-working-group'
-version = '3.1.1'
+version = '3.2.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 2 - 2
runtime-modules/working-group/src/lib.rs

@@ -78,7 +78,7 @@ pub use types::{
 pub type StakeId<T> = <T as stake::Trait>::StakeId;
 
 /// Member identifier in membership::member module
-pub type MemberId<T> = <T as membership::Trait>::MemberId;
+pub type MemberId<T> = <T as common::MembershipTypes>::MemberId;
 
 /// Workaround for BTreeSet type
 pub type ApplicationIdSet<T> = BTreeSet<ApplicationId<T>>;
@@ -109,7 +109,7 @@ pub type NegativeImbalance<T> = <<T as stake::Trait>::Currency as Currency<
 pub type ApplicationIdToWorkerIdMap<T> = BTreeMap<ApplicationId<T>, WorkerId<T>>;
 
 /// Type identifier for worker role, which must be same as membership actor identifier
-pub type WorkerId<T> = <T as membership::Trait>::ActorId;
+pub type WorkerId<T> = <T as common::MembershipTypes>::ActorId;
 
 /// Alias for the application id from the hiring module.
 pub type HiringApplicationId<T> = <T as hiring::Trait>::ApplicationId;

+ 5 - 2
runtime-modules/working-group/src/tests/mock.rs

@@ -101,12 +101,15 @@ parameter_types! {
     pub const ScreenedMemberMaxInitialBalance: u64 = 500;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
 impl membership::Trait for Test {
     type Event = TestEvent;
-    type MemberId = u64;
     type PaidTermId = u64;
     type SubscriptionId = u64;
-    type ActorId = u64;
     type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
 }
 

+ 1 - 1
runtime/src/integration/proposals/membership_origin_validator.rs

@@ -6,7 +6,7 @@ use common::origin::ActorOriginValidator;
 use frame_system::ensure_signed;
 
 /// Member of the Joystream organization
-pub type MemberId<T> = <T as membership::Trait>::MemberId;
+pub type MemberId<T> = <T as common::MembershipTypes>::MemberId;
 
 /// Default membership actor origin validator.
 pub struct MembershipOriginValidator<T> {

+ 9 - 1
runtime/src/integration/proposals/proposal_encoder.rs

@@ -23,7 +23,15 @@ macro_rules! wrap_working_group_call {
             WorkingGroup::Distribution => {
                 Call::DistributionWorkingGroup($working_group_instance_call)
             }
-            WorkingGroup::Operations => Call::OperationsWorkingGroup($working_group_instance_call),
+            WorkingGroup::OperationsAlpha => {
+                Call::OperationsWorkingGroupAlpha($working_group_instance_call)
+            }
+            WorkingGroup::OperationsBeta => {
+                Call::OperationsWorkingGroupBeta($working_group_instance_call)
+            }
+            WorkingGroup::OperationsGamma => {
+                Call::OperationsWorkingGroupGamma($working_group_instance_call)
+            }
             WorkingGroup::Gateway => Call::GatewayWorkingGroup($working_group_instance_call),
         }
     }};

+ 88 - 156
runtime/src/integration/working_group.rs

@@ -2,185 +2,117 @@ use frame_support::StorageMap;
 use sp_std::marker::PhantomData;
 
 use crate::{
-    ContentWorkingGroupInstance, GatewayWorkingGroupInstance, OperationsWorkingGroupInstance,
-    StorageWorkingGroupInstance,
+    ContentWorkingGroupInstance, DistributionWorkingGroupInstance, GatewayWorkingGroupInstance,
+    OperationsWorkingGroupInstanceAlpha, OperationsWorkingGroupInstanceBeta,
+    OperationsWorkingGroupInstanceGamma, StorageWorkingGroupInstance,
 };
 use stake::{BalanceOf, NegativeImbalance};
 
+macro_rules! wg_staking_event_impl {
+    ($operation_wg_instance:ident, $operation_wg_staking_event_handler:ty) => {
+        impl<T: stake::Trait + working_group::Trait<$operation_wg_instance>>
+            stake::StakingEventsHandler<T> for $operation_wg_staking_event_handler
+        {
+            /// Unstake remaining sum back to the source_account_id
+            fn unstaked(
+                stake_id: &<T as stake::Trait>::StakeId,
+                _unstaked_amount: BalanceOf<T>,
+                remaining_imbalance: NegativeImbalance<T>,
+            ) -> NegativeImbalance<T> {
+                // Stake not related to a staked role managed by the hiring module.
+                if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
+                return remaining_imbalance;
+            }
+
+            let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
+
+            if working_group::MemberIdByHiringApplicationId::<T, $operation_wg_instance>::contains_key(
+                hiring_application_id,
+            ) {
+                return <working_group::Module<T, $operation_wg_instance>>::refund_working_group_stake(
+                *stake_id,
+                remaining_imbalance,
+                );
+            }
+
+                remaining_imbalance
+            }
+
+            /// Empty handler for the slashing.
+            fn slashed(
+                _: &<T as stake::Trait>::StakeId,
+                _: Option<<T as stake::Trait>::SlashId>,
+                _: BalanceOf<T>,
+                _: BalanceOf<T>,
+                remaining_imbalance: NegativeImbalance<T>,
+            ) -> NegativeImbalance<T> {
+                remaining_imbalance
+            }
+        }
+    }
+}
+
 // Will be removed in the next releases.
 #[allow(clippy::upper_case_acronyms)]
 pub struct ContentDirectoryWgStakingEventsHandler<T> {
     pub marker: PhantomData<T>,
 }
 
-impl<T: stake::Trait + working_group::Trait<ContentWorkingGroupInstance>>
-    stake::StakingEventsHandler<T> for ContentDirectoryWgStakingEventsHandler<T>
-{
-    /// Unstake remaining sum back to the source_account_id
-    fn unstaked(
-        stake_id: &<T as stake::Trait>::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        // Stake not related to a staked role managed by the hiring module.
-        if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
-            return remaining_imbalance;
-        }
-
-        let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
-
-        if working_group::MemberIdByHiringApplicationId::<T, ContentWorkingGroupInstance>::contains_key(
-            hiring_application_id,
-        ) {
-            return <working_group::Module<T, ContentWorkingGroupInstance>>::refund_working_group_stake(
-				*stake_id,
-				remaining_imbalance,
-			);
-        }
-
-        remaining_imbalance
-    }
-
-    /// Empty handler for the slashing.
-    fn slashed(
-        _: &<T as stake::Trait>::StakeId,
-        _: Option<<T as stake::Trait>::SlashId>,
-        _: BalanceOf<T>,
-        _: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        remaining_imbalance
-    }
-}
-
 pub struct StorageWgStakingEventsHandler<T> {
     pub marker: PhantomData<T>,
 }
 
-impl<T: stake::Trait + working_group::Trait<StorageWorkingGroupInstance>>
-    stake::StakingEventsHandler<T> for StorageWgStakingEventsHandler<T>
-{
-    /// Unstake remaining sum back to the source_account_id
-    fn unstaked(
-        stake_id: &<T as stake::Trait>::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        // Stake not related to a staked role managed by the hiring module.
-        if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
-            return remaining_imbalance;
-        }
-
-        let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
-
-        if working_group::MemberIdByHiringApplicationId::<T, StorageWorkingGroupInstance>::contains_key(
-            hiring_application_id,
-        ) {
-            return <working_group::Module<T, StorageWorkingGroupInstance>>::refund_working_group_stake(
-				*stake_id,
-				remaining_imbalance,
-			);
-        }
-
-        remaining_imbalance
-    }
-
-    /// Empty handler for the slashing.
-    fn slashed(
-        _: &<T as stake::Trait>::StakeId,
-        _: Option<<T as stake::Trait>::SlashId>,
-        _: BalanceOf<T>,
-        _: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        remaining_imbalance
-    }
+pub struct OperationsWgStakingEventsHandlerAlpha<T> {
+    pub marker: PhantomData<T>,
 }
 
-pub struct OperationsWgStakingEventsHandler<T> {
+pub struct OperationsWgStakingEventsHandlerBeta<T> {
     pub marker: PhantomData<T>,
 }
 
-impl<T: stake::Trait + working_group::Trait<OperationsWorkingGroupInstance>>
-    stake::StakingEventsHandler<T> for OperationsWgStakingEventsHandler<T>
-{
-    /// Unstake remaining sum back to the source_account_id
-    fn unstaked(
-        stake_id: &<T as stake::Trait>::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        // Stake not related to a staked role managed by the hiring module.
-        if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
-            return remaining_imbalance;
-        }
-
-        let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
-
-        if working_group::MemberIdByHiringApplicationId::<T, OperationsWorkingGroupInstance>::contains_key(
-            hiring_application_id,
-        ) {
-            return <working_group::Module<T, OperationsWorkingGroupInstance>>::refund_working_group_stake(
-				*stake_id,
-				remaining_imbalance,
-			);
-        }
-
-        remaining_imbalance
-    }
-
-    /// Empty handler for the slashing.
-    fn slashed(
-        _: &<T as stake::Trait>::StakeId,
-        _: Option<<T as stake::Trait>::SlashId>,
-        _: BalanceOf<T>,
-        _: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        remaining_imbalance
-    }
+pub struct OperationsWgStakingEventsHandlerGamma<T> {
+    pub marker: PhantomData<T>,
 }
 
 pub struct GatewayWgStakingEventsHandler<T> {
     pub marker: PhantomData<T>,
 }
 
-impl<T: stake::Trait + working_group::Trait<GatewayWorkingGroupInstance>>
-    stake::StakingEventsHandler<T> for GatewayWgStakingEventsHandler<T>
-{
-    /// Unstake remaining sum back to the source_account_id
-    fn unstaked(
-        stake_id: &<T as stake::Trait>::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        // Stake not related to a staked role managed by the hiring module.
-        if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
-            return remaining_imbalance;
-        }
-
-        let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
-
-        if working_group::MemberIdByHiringApplicationId::<T, GatewayWorkingGroupInstance>::contains_key(
-            hiring_application_id,
-        ) {
-            return <working_group::Module<T, GatewayWorkingGroupInstance>>::refund_working_group_stake(
-				*stake_id,
-				remaining_imbalance,
-			);
-        }
+pub struct DistributionWgStakingEventsHandler<T> {
+    pub marker: PhantomData<T>,
+}
 
-        remaining_imbalance
-    }
+wg_staking_event_impl!(
+    ContentWorkingGroupInstance,
+    ContentDirectoryWgStakingEventsHandler<T>
+);
 
-    /// Empty handler for the slashing.
-    fn slashed(
-        _: &<T as stake::Trait>::StakeId,
-        _: Option<<T as stake::Trait>::SlashId>,
-        _: BalanceOf<T>,
-        _: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        remaining_imbalance
-    }
-}
+wg_staking_event_impl!(
+    StorageWorkingGroupInstance,
+    StorageWgStakingEventsHandler<T>
+);
+
+wg_staking_event_impl!(
+    GatewayWorkingGroupInstance,
+    GatewayWgStakingEventsHandler<T>
+);
+
+wg_staking_event_impl!(
+    OperationsWorkingGroupInstanceAlpha,
+    OperationsWgStakingEventsHandlerAlpha<T>
+);
+
+wg_staking_event_impl!(
+    OperationsWorkingGroupInstanceBeta,
+    OperationsWgStakingEventsHandlerBeta<T>
+);
+
+wg_staking_event_impl!(
+    OperationsWorkingGroupInstanceGamma,
+    OperationsWgStakingEventsHandlerGamma<T>
+);
+
+wg_staking_event_impl!(
+    DistributionWorkingGroupInstance,
+    DistributionWgStakingEventsHandler<T>
+);

+ 35 - 11
runtime/src/lib.rs

@@ -471,15 +471,24 @@ impl stake::Trait for Runtime {
     type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
     type StakePoolId = StakePoolId;
     type StakingEventsHandler = (
-        crate::integration::proposals::StakingEventsHandler<Self>,
         (
             (
+                crate::integration::proposals::StakingEventsHandler<Self>,
                 crate::integration::working_group::ContentDirectoryWgStakingEventsHandler<Self>,
+            ),
+            (
                 crate::integration::working_group::StorageWgStakingEventsHandler<Self>,
+                crate::integration::working_group::OperationsWgStakingEventsHandlerAlpha<Self>,
+            ),
+        ),
+        (
+            (
+                crate::integration::working_group::OperationsWgStakingEventsHandlerBeta<Self>,
+                crate::integration::working_group::OperationsWgStakingEventsHandlerGamma<Self>,
             ),
             (
-                crate::integration::working_group::OperationsWgStakingEventsHandler<Self>,
                 crate::integration::working_group::GatewayWgStakingEventsHandler<Self>,
+                crate::integration::working_group::DistributionWgStakingEventsHandler<Self>,
             ),
         ),
     );
@@ -522,10 +531,8 @@ parameter_types! {
 
 impl membership::Trait for Runtime {
     type Event = Event;
-    type MemberId = MemberId;
     type PaidTermId = u64;
     type SubscriptionId = u64;
-    type ActorId = ActorId;
     type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
 }
 
@@ -545,12 +552,18 @@ pub type ContentWorkingGroupInstance = working_group::Instance3;
 // The distribution working group instance alias.
 pub type DistributionWorkingGroupInstance = working_group::Instance6;
 
-// The builder working group instance alias.
-pub type OperationsWorkingGroupInstance = working_group::Instance4;
-
 // The gateway working group instance alias.
 pub type GatewayWorkingGroupInstance = working_group::Instance5;
 
+// The operation working group alpha instance alias.
+pub type OperationsWorkingGroupInstanceAlpha = working_group::Instance4;
+
+// The operation working group beta instance alias .
+pub type OperationsWorkingGroupInstanceBeta = working_group::Instance7;
+
+// The operation working group gamma instance alias .
+pub type OperationsWorkingGroupInstanceGamma = working_group::Instance8;
+
 parameter_types! {
     pub const MaxWorkerNumberLimit: u32 = 100;
 }
@@ -570,7 +583,7 @@ impl working_group::Trait<DistributionWorkingGroupInstance> for Runtime {
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
 }
 
-impl working_group::Trait<OperationsWorkingGroupInstance> for Runtime {
+impl working_group::Trait<OperationsWorkingGroupInstanceAlpha> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
 }
@@ -580,6 +593,16 @@ impl working_group::Trait<GatewayWorkingGroupInstance> for Runtime {
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
 }
 
+impl working_group::Trait<OperationsWorkingGroupInstanceBeta> for Runtime {
+    type Event = Event;
+    type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+}
+
+impl working_group::Trait<OperationsWorkingGroupInstanceGamma> for Runtime {
+    type Event = Event;
+    type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+}
+
 parameter_types! {
     pub const ProposalCancellationFee: u64 = 10000;
     pub const ProposalRejectionFee: u64 = 5000;
@@ -779,14 +802,15 @@ construct_runtime!(
         ProposalsEngine: proposals_engine::{Module, Call, Storage, Event<T>},
         ProposalsDiscussion: proposals_discussion::{Module, Call, Storage, Event<T>},
         ProposalsCodex: proposals_codex::{Module, Call, Storage, Config<T>},
+        Storage: storage::{Module, Call, Storage, Event<T>},
         // --- Working groups
         // reserved for the future use: ForumWorkingGroup: working_group::<Instance1>::{Module, Call, Storage, Config<T>, Event<T>},
         StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Config<T>, Event<T>},
         ContentWorkingGroup: working_group::<Instance3>::{Module, Call, Storage, Config<T>, Event<T>},
-        OperationsWorkingGroup: working_group::<Instance4>::{Module, Call, Storage, Config<T>, Event<T>},
+        OperationsWorkingGroupAlpha: working_group::<Instance4>::{Module, Call, Storage, Config<T>, Event<T>},
         GatewayWorkingGroup: working_group::<Instance5>::{Module, Call, Storage, Config<T>, Event<T>},
         DistributionWorkingGroup: working_group::<Instance6>::{Module, Call, Storage, Config<T>, Event<T>},
-        //
-        Storage: storage::{Module, Call, Storage, Event<T>},
+        OperationsWorkingGroupBeta: working_group::<Instance7>::{Module, Call, Storage, Config<T>, Event<T>},
+        OperationsWorkingGroupGamma: working_group::<Instance8>::{Module, Call, Storage, Config<T>, Event<T>},
     }
 );

+ 0 - 4
runtime/src/primitives.rs

@@ -14,10 +14,6 @@ pub type TransactionPriority = u64;
 /// Alias for ContentId, used in various places.
 pub type ContentId = sp_core::H256;
 
-#[allow(clippy::upper_case_acronyms)]
-/// Alias for DAOId, used in various places.
-pub type DAOId = u64;
-
 /// Alias for DataObjectTypeId, used in various places.
 pub type DataObjectTypeId = u64;
 

+ 169 - 45
runtime/src/tests/proposals_integration/working_group_proposals.rs

@@ -13,8 +13,10 @@ use working_group::{OpeningPolicyCommitment, RewardPolicy};
 use crate::{
     Balance, BlockNumber, ContentWorkingGroup, ContentWorkingGroupInstance,
     DistributionWorkingGroup, DistributionWorkingGroupInstance, GatewayWorkingGroup,
-    GatewayWorkingGroupInstance, OperationsWorkingGroup, OperationsWorkingGroupInstance,
-    StorageWorkingGroup, StorageWorkingGroupInstance,
+    GatewayWorkingGroupInstance, OperationsWorkingGroupAlpha, OperationsWorkingGroupBeta,
+    OperationsWorkingGroupGamma, OperationsWorkingGroupInstanceAlpha,
+    OperationsWorkingGroupInstanceBeta, OperationsWorkingGroupInstanceGamma, StorageWorkingGroup,
+    StorageWorkingGroupInstance,
 };
 use sp_std::collections::btree_set::BTreeSet;
 
@@ -62,11 +64,27 @@ fn add_opening(
             >>::contains_key(opening_id));
             opening_id
         }
-        WorkingGroup::Operations => {
-            let opening_id = OperationsWorkingGroup::next_opening_id();
+        WorkingGroup::OperationsAlpha => {
+            let opening_id = OperationsWorkingGroupAlpha::next_opening_id();
             assert!(!<working_group::OpeningById<
                 Runtime,
-                OperationsWorkingGroupInstance,
+                OperationsWorkingGroupInstanceAlpha,
+            >>::contains_key(opening_id));
+            opening_id
+        }
+        WorkingGroup::OperationsBeta => {
+            let opening_id = OperationsWorkingGroupBeta::next_opening_id();
+            assert!(!<working_group::OpeningById<
+                Runtime,
+                OperationsWorkingGroupInstanceBeta,
+            >>::contains_key(opening_id));
+            opening_id
+        }
+        WorkingGroup::OperationsGamma => {
+            let opening_id = OperationsWorkingGroupGamma::next_opening_id();
+            assert!(!<working_group::OpeningById<
+                Runtime,
+                OperationsWorkingGroupInstanceGamma,
             >>::contains_key(opening_id));
             opening_id
         }
@@ -362,10 +380,22 @@ fn create_add_working_group_leader_opening_proposal_execution_succeeds() {
                     DistributionWorkingGroupInstance,
                 >(group);
             }
-            WorkingGroup::Operations => {
+            WorkingGroup::OperationsAlpha => {
                 run_create_add_working_group_leader_opening_proposal_execution_succeeds::<
                     Runtime,
-                    OperationsWorkingGroupInstance,
+                    OperationsWorkingGroupInstanceAlpha,
+                >(group);
+            }
+            WorkingGroup::OperationsBeta => {
+                run_create_add_working_group_leader_opening_proposal_execution_succeeds::<
+                    Runtime,
+                    OperationsWorkingGroupInstanceBeta,
+                >(group);
+            }
+            WorkingGroup::OperationsGamma => {
+                run_create_add_working_group_leader_opening_proposal_execution_succeeds::<
+                    Runtime,
+                    OperationsWorkingGroupInstanceGamma,
                 >(group);
             }
             WorkingGroup::Gateway => {
@@ -384,7 +414,7 @@ fn run_create_add_working_group_leader_opening_proposal_execution_succeeds<
 >(
     working_group: WorkingGroup,
 ) where
-    <T as membership::Trait>::MemberId: From<u64>,
+    <T as common::MembershipTypes>::MemberId: From<u64>,
     <T as hiring::Trait>::OpeningId: From<u64>,
 {
     initial_test_ext().execute_with(|| {
@@ -434,16 +464,29 @@ fn create_begin_review_working_group_leader_applications_proposal_execution_succ
             }
             WorkingGroup::Distribution => {
                 run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds::<
-                Runtime,
+                    Runtime,
                     DistributionWorkingGroupInstance,
+                >(group);
+            }
+            WorkingGroup::OperationsAlpha => {
+                run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds::<
+                Runtime,
+                OperationsWorkingGroupInstanceAlpha,
+            >(group);
+            }
+            WorkingGroup::OperationsBeta => {
+                run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds::<
+                Runtime,
+                OperationsWorkingGroupInstanceBeta,
             >(group);
             }
-            WorkingGroup::Operations => {
+            WorkingGroup::OperationsGamma => {
                 run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds::<
                 Runtime,
-                OperationsWorkingGroupInstance,
+                OperationsWorkingGroupInstanceGamma,
             >(group);
             }
+
             WorkingGroup::Gateway => {
                 run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds::<
                 Runtime,
@@ -536,12 +579,25 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     DistributionWorkingGroupInstance,
                 >(group);
             }
-            WorkingGroup::Operations => {
+            WorkingGroup::OperationsAlpha => {
+                run_create_fill_working_group_leader_opening_proposal_execution_succeeds::<
+                    Runtime,
+                    OperationsWorkingGroupInstanceAlpha,
+                >(group);
+            }
+            WorkingGroup::OperationsBeta => {
+                run_create_fill_working_group_leader_opening_proposal_execution_succeeds::<
+                    Runtime,
+                    OperationsWorkingGroupInstanceBeta,
+                >(group);
+            }
+            WorkingGroup::OperationsGamma => {
                 run_create_fill_working_group_leader_opening_proposal_execution_succeeds::<
                     Runtime,
-                    OperationsWorkingGroupInstance,
+                    OperationsWorkingGroupInstanceGamma,
                 >(group);
             }
+
             WorkingGroup::Gateway => {
                 run_create_fill_working_group_leader_opening_proposal_execution_succeeds::<
                     Runtime,
@@ -558,7 +614,7 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
         working_group: WorkingGroup,
     ) where
         <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-        <T as membership::Trait>::MemberId: From<u64>,
+        <T as common::MembershipTypes>::MemberId: From<u64>,
         <T as hiring::Trait>::OpeningId: From<u64>,
     {
         initial_test_ext().execute_with(|| {
@@ -631,12 +687,25 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                         DistributionWorkingGroupInstance,
                     >(group);
                 }
-                WorkingGroup::Operations => {
+                WorkingGroup::OperationsAlpha => {
+                    run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
+                        Runtime,
+                        OperationsWorkingGroupInstanceAlpha,
+                    >(group);
+                }
+                WorkingGroup::OperationsBeta => {
+                    run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
+                        Runtime,
+                        OperationsWorkingGroupInstanceBeta,
+                    >(group);
+                }
+                WorkingGroup::OperationsGamma => {
                     run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
                         Runtime,
-                        OperationsWorkingGroupInstance,
+                        OperationsWorkingGroupInstanceGamma,
                     >(group);
                 }
+
                 WorkingGroup::Gateway => {
                     run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
                         Runtime,
@@ -655,8 +724,8 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
     ) where
         <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
         <T as hiring::Trait>::OpeningId: From<u64>,
-        <T as membership::Trait>::MemberId: From<u64>,
-        <T as membership::Trait>::ActorId: Into<u64>,
+        <T as common::MembershipTypes>::MemberId: From<u64>,
+        <T as common::MembershipTypes>::ActorId: Into<u64>,
         <<T as stake::Trait>::Currency as traits::Currency<
             <T as frame_system::Trait>::AccountId,
         >>::Balance: From<u128>,
@@ -766,10 +835,22 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                         DistributionWorkingGroupInstance,
                     >(group)
                 }
-                WorkingGroup::Operations => {
+                WorkingGroup::OperationsAlpha => {
+                    run_create_slash_group_leader_stake_proposal_execution_succeeds::<
+                        Runtime,
+                        OperationsWorkingGroupInstanceAlpha,
+                    >(group)
+                }
+                WorkingGroup::OperationsBeta => {
+                    run_create_slash_group_leader_stake_proposal_execution_succeeds::<
+                        Runtime,
+                        OperationsWorkingGroupInstanceBeta,
+                    >(group)
+                }
+                WorkingGroup::OperationsGamma => {
                     run_create_slash_group_leader_stake_proposal_execution_succeeds::<
                         Runtime,
-                        OperationsWorkingGroupInstance,
+                        OperationsWorkingGroupInstanceGamma,
                     >(group)
                 }
                 WorkingGroup::Gateway => {
@@ -790,8 +871,8 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
     ) where
         <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
         <T as hiring::Trait>::OpeningId: From<u64>,
-        <T as membership::Trait>::MemberId: From<u64>,
-        <T as membership::Trait>::ActorId: Into<u64>,
+        <T as common::MembershipTypes>::MemberId: From<u64>,
+        <T as common::MembershipTypes>::ActorId: Into<u64>,
         <<T as stake::Trait>::Currency as traits::Currency<
             <T as frame_system::Trait>::AccountId,
         >>::Balance: From<u128>,
@@ -902,11 +983,23 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                         DistributionWorkingGroupInstance,
                     >(group);
                 }
-                WorkingGroup::Operations => {
+                WorkingGroup::OperationsAlpha => {
                     run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
                         Runtime,
-                        OperationsWorkingGroupInstance,
-                    >(group);
+                        OperationsWorkingGroupInstanceAlpha,
+                    >(group)
+                }
+                WorkingGroup::OperationsBeta => {
+                    run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                        Runtime,
+                        OperationsWorkingGroupInstanceBeta,
+                    >(group)
+                }
+                WorkingGroup::OperationsGamma => {
+                    run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                        Runtime,
+                        OperationsWorkingGroupInstanceGamma,
+                    >(group)
                 }
                 WorkingGroup::Gateway => {
                     run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
@@ -924,7 +1017,7 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             working_group: WorkingGroup,
         ) where
             <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-            <T as membership::Trait>::MemberId: From<u64>,
+            <T as common::MembershipTypes>::MemberId: From<u64>,
             <T as minting::Trait>::MintId: From<u64>,
             <<T as minting::Trait>::Currency as traits::Currency<
                 <T as frame_system::Trait>::AccountId,
@@ -959,31 +1052,43 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             for group in WorkingGroup::iter() {
                 match group {
                     WorkingGroup::Content => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                        run_create_set_group_leader_reward_proposal_execution_succeeds::<
                             Runtime,
                             ContentWorkingGroupInstance,
                         >(group);
                     }
                     WorkingGroup::Storage => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                        run_create_set_group_leader_reward_proposal_execution_succeeds::<
                             Runtime,
                             StorageWorkingGroupInstance,
                         >(group);
                     }
                     WorkingGroup::Distribution => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                        run_create_set_group_leader_reward_proposal_execution_succeeds::<
                             Runtime,
                             DistributionWorkingGroupInstance,
                         >(group);
                     }
-                    WorkingGroup::Operations => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                    WorkingGroup::OperationsAlpha => {
+                        run_create_set_group_leader_reward_proposal_execution_succeeds::<
                             Runtime,
-                            OperationsWorkingGroupInstance,
-                        >(group);
+                            OperationsWorkingGroupInstanceAlpha,
+                        >(group)
+                    }
+                    WorkingGroup::OperationsBeta => {
+                        run_create_set_group_leader_reward_proposal_execution_succeeds::<
+                            Runtime,
+                            OperationsWorkingGroupInstanceBeta,
+                        >(group)
+                    }
+                    WorkingGroup::OperationsGamma => {
+                        run_create_set_group_leader_reward_proposal_execution_succeeds::<
+                            Runtime,
+                            OperationsWorkingGroupInstanceGamma,
+                        >(group)
                     }
                     WorkingGroup::Gateway => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                        run_create_set_group_leader_reward_proposal_execution_succeeds::<
                             Runtime,
                             GatewayWorkingGroupInstance,
                         >(group);
@@ -999,8 +1104,8 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             working_group: WorkingGroup,
         ) where
             <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-            <T as membership::Trait>::MemberId: From<u64>,
-            <T as membership::Trait>::ActorId: Into<u64>,
+            <T as common::MembershipTypes>::MemberId: From<u64>,
+            <T as common::MembershipTypes>::ActorId: Into<u64>,
             <T as minting::Trait>::MintId: From<u64>,
             <T as hiring::Trait>::OpeningId: From<u64>,
             <<T as minting::Trait>::Currency as traits::Currency<
@@ -1117,12 +1222,25 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                             DistributionWorkingGroupInstance,
                         >(group);
                     }
-                    WorkingGroup::Operations => {
+                    WorkingGroup::OperationsAlpha => {
                         run_create_terminate_group_leader_role_proposal_execution_succeeds::<
                             Runtime,
-                            OperationsWorkingGroupInstance,
-                        >(group);
+                            OperationsWorkingGroupInstanceAlpha,
+                        >(group)
+                    }
+                    WorkingGroup::OperationsBeta => {
+                        run_create_terminate_group_leader_role_proposal_execution_succeeds::<
+                            Runtime,
+                            OperationsWorkingGroupInstanceBeta,
+                        >(group)
+                    }
+                    WorkingGroup::OperationsGamma => {
+                        run_create_terminate_group_leader_role_proposal_execution_succeeds::<
+                            Runtime,
+                            OperationsWorkingGroupInstanceGamma,
+                        >(group)
                     }
+
                     WorkingGroup::Gateway => {
                         run_create_terminate_group_leader_role_proposal_execution_succeeds::<
                             Runtime,
@@ -1140,8 +1258,8 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             working_group: WorkingGroup,
         ) where
             <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-            <T as membership::Trait>::MemberId: From<u64>,
-            <T as membership::Trait>::ActorId: Into<u64>,
+            <T as common::MembershipTypes>::MemberId: From<u64>,
+            <T as common::MembershipTypes>::ActorId: Into<u64>,
             <T as minting::Trait>::MintId: From<u64>,
             <T as hiring::Trait>::OpeningId: From<u64>,
             <<T as stake::Trait>::Currency as traits::Currency<
@@ -1251,8 +1369,14 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     WorkingGroup::Distribution => {
                         run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, DistributionWorkingGroupInstance>(group);
                     }
-                    WorkingGroup::Operations => {
-                        run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, OperationsWorkingGroupInstance>(group);
+                    WorkingGroup::OperationsAlpha => {
+                        run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, OperationsWorkingGroupInstanceAlpha>(group);
+                    }
+                    WorkingGroup::OperationsBeta => {
+                        run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, OperationsWorkingGroupInstanceBeta>(group);
+                    }
+                    WorkingGroup::OperationsGamma => {
+                        run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, OperationsWorkingGroupInstanceGamma>(group);
                     }
                     WorkingGroup::Gateway => {
                         run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, GatewayWorkingGroupInstance>(group);
@@ -1268,8 +1392,8 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             working_group: WorkingGroup,
         ) where
             <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-            <T as membership::Trait>::MemberId: From<u64>,
-            <T as membership::Trait>::ActorId: Into<u64>,
+            <T as common::MembershipTypes>::MemberId: From<u64>,
+            <T as common::MembershipTypes>::ActorId: Into<u64>,
             <T as minting::Trait>::MintId: From<u64>,
             <T as hiring::Trait>::OpeningId: From<u64>,
             <<T as stake::Trait>::Currency as traits::Currency<

File diff suppressed because it is too large
+ 1 - 1
types/augment-codec/all.ts


+ 13 - 1
types/augment-codec/augment-api-consts.ts

@@ -69,7 +69,19 @@ declare module '@polkadot/api/types/consts' {
     members: {
       screenedMemberMaxInitialBalance: BalanceOf & AugmentedConst<ApiType>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Exports const -  max simultaneous active worker number.
+       **/
+      maxWorkerNumberLimit: u32 & AugmentedConst<ApiType>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Exports const -  max simultaneous active worker number.
+       **/
+      maxWorkerNumberLimit: u32 & AugmentedConst<ApiType>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Exports const -  max simultaneous active worker number.
        **/

+ 797 - 1
types/augment-codec/augment-api-errors.ts

@@ -1475,7 +1475,803 @@ declare module '@polkadot/api/types/errors' {
        **/
       UnsignedOrigin: AugmentedError<ApiType>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Opening does not exist.
+       **/
+      AcceptWorkerApplicationsOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting to begin.
+       **/
+      AcceptWorkerApplicationsOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Opening does not activate in the future.
+       **/
+      AddWorkerOpeningActivatesInThePast: AugmentedError<ApiType>;
+      /**
+       * Add worker opening application stake cannot be zero.
+       **/
+      AddWorkerOpeningApplicationStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Application stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningAppliicationStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * New application was crowded out.
+       **/
+      AddWorkerOpeningNewApplicationWasCrowdedOut: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      AddWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening is not in accepting applications stage.
+       **/
+      AddWorkerOpeningOpeningNotInAcceptingApplicationStage: AugmentedError<ApiType>;
+      /**
+       * Add worker opening role stake cannot be zero.
+       **/
+      AddWorkerOpeningRoleStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Role stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningRoleStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * Stake amount too low.
+       **/
+      AddWorkerOpeningStakeAmountTooLow: AugmentedError<ApiType>;
+      /**
+       * Stake missing when required.
+       **/
+      AddWorkerOpeningStakeMissingWhenRequired: AugmentedError<ApiType>;
+      /**
+       * Stake provided when redundant.
+       **/
+      AddWorkerOpeningStakeProvidedWhenRedundant: AugmentedError<ApiType>;
+      /**
+       * Application rationing has zero max active applicants.
+       **/
+      AddWorkerOpeningZeroMaxApplicantCount: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_rationing_policy):
+       * max_active_applicants should be non-zero.
+       **/
+      ApplicationRationingPolicyMaxActiveApplicantsIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer does not match controller account.
+       **/
+      ApplyOnWorkerOpeningSignerNotControllerAccount: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      BeginWorkerApplicantReviewOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting.
+       **/
+      BeginWorkerApplicantReviewOpeningOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Cannot find mint in the minting module.
+       **/
+      CannotFindMint: AugmentedError<ApiType>;
+      /**
+       * There is leader already, cannot hire another one.
+       **/
+      CannotHireLeaderWhenLeaderExists: AugmentedError<ApiType>;
+      /**
+       * Cannot fill opening with multiple applications.
+       **/
+      CannotHireMultipleLeaders: AugmentedError<ApiType>;
+      /**
+       * Current lead is not set.
+       **/
+      CurrentLeadNotSet: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_application_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_role_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Reward policy has invalid next payment block number.
+       **/
+      FillOpeningInvalidNextPaymentBlock: AugmentedError<ApiType>;
+      /**
+       * Working group mint does not exist.
+       **/
+      FillOpeningMintDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_successful_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningSuccessfulApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Applications not for opening.
+       **/
+      FillWorkerOpeningApplicationForWrongOpening: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      FullWorkerOpeningApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application not in active stage.
+       **/
+      FullWorkerOpeningApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * OpeningDoesNotExist.
+       **/
+      FullWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening not in review period stage.
+       **/
+      FullWorkerOpeningOpeningNotInReviewPeriodStage: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to apply.
+       **/
+      InsufficientBalanceToApply: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to cover stake.
+       **/
+      InsufficientBalanceToCoverStake: AugmentedError<ApiType>;
+      /**
+       * Not a lead account.
+       **/
+      IsNotLeadAccount: AugmentedError<ApiType>;
+      /**
+       * Working group size limit exceeded.
+       **/
+      MaxActiveWorkerNumberExceeded: AugmentedError<ApiType>;
+      /**
+       * Member already has an active application on the opening.
+       **/
+      MemberHasActiveApplicationOnOpening: AugmentedError<ApiType>;
+      /**
+       * Member id is invalid.
+       **/
+      MembershipInvalidMemberId: AugmentedError<ApiType>;
+      /**
+       * Unsigned origin.
+       **/
+      MembershipUnsignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Minting error: NextAdjustmentInPast
+       **/
+      MintingErrorNextAdjustmentInPast: AugmentedError<ApiType>;
+      /**
+       * Cannot get the worker stake profile.
+       **/
+      NoWorkerStakeProfile: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      OpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening text too long.
+       **/
+      OpeningTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Opening text too short.
+       **/
+      OpeningTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Origin must be controller or root account of member.
+       **/
+      OriginIsNeitherMemberControllerOrRoot: AugmentedError<ApiType>;
+      /**
+       * Origin is not applicant.
+       **/
+      OriginIsNotApplicant: AugmentedError<ApiType>;
+      /**
+       * Next payment is not in the future.
+       **/
+      RecurringRewardsNextPaymentNotInFuture: AugmentedError<ApiType>;
+      /**
+       * Recipient not found.
+       **/
+      RecurringRewardsRecipientNotFound: AugmentedError<ApiType>;
+      /**
+       * Reward relationship not found.
+       **/
+      RecurringRewardsRewardRelationshipNotFound: AugmentedError<ApiType>;
+      /**
+       * Recipient reward source not found.
+       **/
+      RecurringRewardsRewardSourceNotFound: AugmentedError<ApiType>;
+      /**
+       * Relationship must exist.
+       **/
+      RelationshipMustExist: AugmentedError<ApiType>;
+      /**
+       * Require root origin in extrinsics.
+       **/
+      RequireRootOrigin: AugmentedError<ApiType>;
+      /**
+       * Require signed origin in extrinsics.
+       **/
+      RequireSignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer is not worker role account.
+       **/
+      SignerIsNotWorkerRoleAccount: AugmentedError<ApiType>;
+      /**
+       * Provided stake balance cannot be zero.
+       **/
+      StakeBalanceCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Already unstaking.
+       **/
+      StakingErrorAlreadyUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot change stake by zero.
+       **/
+      StakingErrorCannotChangeStakeByZero: AugmentedError<ApiType>;
+      /**
+       * Cannot decrease stake while slashes ongoing.
+       **/
+      StakingErrorCannotDecreaseWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Cannot increase stake while unstaking.
+       **/
+      StakingErrorCannotIncreaseStakeWhileUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot unstake while slashes ongoing.
+       **/
+      StakingErrorCannotUnstakeWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance in source account.
+       **/
+      StakingErrorInsufficientBalanceInSourceAccount: AugmentedError<ApiType>;
+      /**
+       * Insufficient stake to decrease.
+       **/
+      StakingErrorInsufficientStake: AugmentedError<ApiType>;
+      /**
+       * Not staked.
+       **/
+      StakingErrorNotStaked: AugmentedError<ApiType>;
+      /**
+       * Slash amount should be greater than zero.
+       **/
+      StakingErrorSlashAmountShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Stake not found.
+       **/
+      StakingErrorStakeNotFound: AugmentedError<ApiType>;
+      /**
+       * Unstaking period should be greater than zero.
+       **/
+      StakingErrorUnstakingPeriodShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Successful worker application does not exist.
+       **/
+      SuccessfulWorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_application_stake_unstaking_period should be non-zero.
+       **/
+      TerminateApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_role_stake_unstaking_period should be non-zero.
+       **/
+      TerminateRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      WithdrawWorkerApplicationApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application is not active.
+       **/
+      WithdrawWorkerApplicationApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * Opening not accepting applications.
+       **/
+      WithdrawWorkerApplicationOpeningNotAcceptingApplications: AugmentedError<ApiType>;
+      /**
+       * Redundant unstaking period provided
+       **/
+      WithdrawWorkerApplicationRedundantUnstakingPeriod: AugmentedError<ApiType>;
+      /**
+       * UnstakingPeriodTooShort .... // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
+       **/
+      WithdrawWorkerApplicationUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker application does not exist.
+       **/
+      WorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker application text too long.
+       **/
+      WorkerApplicationTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker application text too short.
+       **/
+      WorkerApplicationTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker does not exist.
+       **/
+      WorkerDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too long.
+       **/
+      WorkerExitRationaleTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too short.
+       **/
+      WorkerExitRationaleTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker has no recurring reward.
+       **/
+      WorkerHasNoReward: AugmentedError<ApiType>;
+      /**
+       * Worker storage text is too long.
+       **/
+      WorkerStorageValueTooLong: AugmentedError<ApiType>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Opening does not exist.
+       **/
+      AcceptWorkerApplicationsOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting to begin.
+       **/
+      AcceptWorkerApplicationsOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Opening does not activate in the future.
+       **/
+      AddWorkerOpeningActivatesInThePast: AugmentedError<ApiType>;
+      /**
+       * Add worker opening application stake cannot be zero.
+       **/
+      AddWorkerOpeningApplicationStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Application stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningAppliicationStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * New application was crowded out.
+       **/
+      AddWorkerOpeningNewApplicationWasCrowdedOut: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      AddWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening is not in accepting applications stage.
+       **/
+      AddWorkerOpeningOpeningNotInAcceptingApplicationStage: AugmentedError<ApiType>;
+      /**
+       * Add worker opening role stake cannot be zero.
+       **/
+      AddWorkerOpeningRoleStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Role stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningRoleStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * Stake amount too low.
+       **/
+      AddWorkerOpeningStakeAmountTooLow: AugmentedError<ApiType>;
+      /**
+       * Stake missing when required.
+       **/
+      AddWorkerOpeningStakeMissingWhenRequired: AugmentedError<ApiType>;
+      /**
+       * Stake provided when redundant.
+       **/
+      AddWorkerOpeningStakeProvidedWhenRedundant: AugmentedError<ApiType>;
+      /**
+       * Application rationing has zero max active applicants.
+       **/
+      AddWorkerOpeningZeroMaxApplicantCount: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_rationing_policy):
+       * max_active_applicants should be non-zero.
+       **/
+      ApplicationRationingPolicyMaxActiveApplicantsIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer does not match controller account.
+       **/
+      ApplyOnWorkerOpeningSignerNotControllerAccount: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      BeginWorkerApplicantReviewOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting.
+       **/
+      BeginWorkerApplicantReviewOpeningOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Cannot find mint in the minting module.
+       **/
+      CannotFindMint: AugmentedError<ApiType>;
+      /**
+       * There is leader already, cannot hire another one.
+       **/
+      CannotHireLeaderWhenLeaderExists: AugmentedError<ApiType>;
+      /**
+       * Cannot fill opening with multiple applications.
+       **/
+      CannotHireMultipleLeaders: AugmentedError<ApiType>;
+      /**
+       * Current lead is not set.
+       **/
+      CurrentLeadNotSet: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_application_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_role_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Reward policy has invalid next payment block number.
+       **/
+      FillOpeningInvalidNextPaymentBlock: AugmentedError<ApiType>;
+      /**
+       * Working group mint does not exist.
+       **/
+      FillOpeningMintDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_successful_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningSuccessfulApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Applications not for opening.
+       **/
+      FillWorkerOpeningApplicationForWrongOpening: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      FullWorkerOpeningApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application not in active stage.
+       **/
+      FullWorkerOpeningApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * OpeningDoesNotExist.
+       **/
+      FullWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening not in review period stage.
+       **/
+      FullWorkerOpeningOpeningNotInReviewPeriodStage: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to apply.
+       **/
+      InsufficientBalanceToApply: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to cover stake.
+       **/
+      InsufficientBalanceToCoverStake: AugmentedError<ApiType>;
+      /**
+       * Not a lead account.
+       **/
+      IsNotLeadAccount: AugmentedError<ApiType>;
+      /**
+       * Working group size limit exceeded.
+       **/
+      MaxActiveWorkerNumberExceeded: AugmentedError<ApiType>;
+      /**
+       * Member already has an active application on the opening.
+       **/
+      MemberHasActiveApplicationOnOpening: AugmentedError<ApiType>;
+      /**
+       * Member id is invalid.
+       **/
+      MembershipInvalidMemberId: AugmentedError<ApiType>;
+      /**
+       * Unsigned origin.
+       **/
+      MembershipUnsignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Minting error: NextAdjustmentInPast
+       **/
+      MintingErrorNextAdjustmentInPast: AugmentedError<ApiType>;
+      /**
+       * Cannot get the worker stake profile.
+       **/
+      NoWorkerStakeProfile: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      OpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening text too long.
+       **/
+      OpeningTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Opening text too short.
+       **/
+      OpeningTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Origin must be controller or root account of member.
+       **/
+      OriginIsNeitherMemberControllerOrRoot: AugmentedError<ApiType>;
+      /**
+       * Origin is not applicant.
+       **/
+      OriginIsNotApplicant: AugmentedError<ApiType>;
+      /**
+       * Next payment is not in the future.
+       **/
+      RecurringRewardsNextPaymentNotInFuture: AugmentedError<ApiType>;
+      /**
+       * Recipient not found.
+       **/
+      RecurringRewardsRecipientNotFound: AugmentedError<ApiType>;
+      /**
+       * Reward relationship not found.
+       **/
+      RecurringRewardsRewardRelationshipNotFound: AugmentedError<ApiType>;
+      /**
+       * Recipient reward source not found.
+       **/
+      RecurringRewardsRewardSourceNotFound: AugmentedError<ApiType>;
+      /**
+       * Relationship must exist.
+       **/
+      RelationshipMustExist: AugmentedError<ApiType>;
+      /**
+       * Require root origin in extrinsics.
+       **/
+      RequireRootOrigin: AugmentedError<ApiType>;
+      /**
+       * Require signed origin in extrinsics.
+       **/
+      RequireSignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer is not worker role account.
+       **/
+      SignerIsNotWorkerRoleAccount: AugmentedError<ApiType>;
+      /**
+       * Provided stake balance cannot be zero.
+       **/
+      StakeBalanceCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Already unstaking.
+       **/
+      StakingErrorAlreadyUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot change stake by zero.
+       **/
+      StakingErrorCannotChangeStakeByZero: AugmentedError<ApiType>;
+      /**
+       * Cannot decrease stake while slashes ongoing.
+       **/
+      StakingErrorCannotDecreaseWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Cannot increase stake while unstaking.
+       **/
+      StakingErrorCannotIncreaseStakeWhileUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot unstake while slashes ongoing.
+       **/
+      StakingErrorCannotUnstakeWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance in source account.
+       **/
+      StakingErrorInsufficientBalanceInSourceAccount: AugmentedError<ApiType>;
+      /**
+       * Insufficient stake to decrease.
+       **/
+      StakingErrorInsufficientStake: AugmentedError<ApiType>;
+      /**
+       * Not staked.
+       **/
+      StakingErrorNotStaked: AugmentedError<ApiType>;
+      /**
+       * Slash amount should be greater than zero.
+       **/
+      StakingErrorSlashAmountShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Stake not found.
+       **/
+      StakingErrorStakeNotFound: AugmentedError<ApiType>;
+      /**
+       * Unstaking period should be greater than zero.
+       **/
+      StakingErrorUnstakingPeriodShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Successful worker application does not exist.
+       **/
+      SuccessfulWorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_application_stake_unstaking_period should be non-zero.
+       **/
+      TerminateApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_role_stake_unstaking_period should be non-zero.
+       **/
+      TerminateRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      WithdrawWorkerApplicationApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application is not active.
+       **/
+      WithdrawWorkerApplicationApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * Opening not accepting applications.
+       **/
+      WithdrawWorkerApplicationOpeningNotAcceptingApplications: AugmentedError<ApiType>;
+      /**
+       * Redundant unstaking period provided
+       **/
+      WithdrawWorkerApplicationRedundantUnstakingPeriod: AugmentedError<ApiType>;
+      /**
+       * UnstakingPeriodTooShort .... // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
+       **/
+      WithdrawWorkerApplicationUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker application does not exist.
+       **/
+      WorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker application text too long.
+       **/
+      WorkerApplicationTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker application text too short.
+       **/
+      WorkerApplicationTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker does not exist.
+       **/
+      WorkerDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too long.
+       **/
+      WorkerExitRationaleTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too short.
+       **/
+      WorkerExitRationaleTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker has no recurring reward.
+       **/
+      WorkerHasNoReward: AugmentedError<ApiType>;
+      /**
+       * Worker storage text is too long.
+       **/
+      WorkerStorageValueTooLong: AugmentedError<ApiType>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Opening does not exist.
        **/

+ 267 - 5
types/augment-codec/augment-api-events.ts

@@ -565,9 +565,9 @@ declare module '@polkadot/api/types/events' {
       MemberRegistered: AugmentedEvent<ApiType, [MemberId, AccountId, EntryMethod]>;
       MemberSetControllerAccount: AugmentedEvent<ApiType, [MemberId, AccountId]>;
       MemberSetRootAccount: AugmentedEvent<ApiType, [MemberId, AccountId]>;
-      MemberUpdatedAboutText: AugmentedEvent<ApiType, [MemberId]>;
-      MemberUpdatedAvatar: AugmentedEvent<ApiType, [MemberId]>;
-      MemberUpdatedHandle: AugmentedEvent<ApiType, [MemberId]>;
+      MemberUpdatedAboutText: AugmentedEvent<ApiType, [MemberId, Bytes]>;
+      MemberUpdatedAvatar: AugmentedEvent<ApiType, [MemberId, Bytes]>;
+      MemberUpdatedHandle: AugmentedEvent<ApiType, [MemberId, Bytes]>;
     };
     memo: {
       MemoUpdated: AugmentedEvent<ApiType, [AccountId]>;
@@ -581,7 +581,267 @@ declare module '@polkadot/api/types/events' {
        **/
       Offence: AugmentedEvent<ApiType, [Kind, OpaqueTimeSlot, bool]>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Emits on accepting application for the worker opening.
+       * Params:
+       * - Opening id
+       **/
+      AcceptedApplications: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on terminating the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationTerminated: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on withdrawing the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationWithdrawn: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on adding the application for the worker opening.
+       * Params:
+       * - Opening id
+       * - Application id
+       **/
+      AppliedOnOpening: AugmentedEvent<ApiType, [OpeningId, ApplicationId]>;
+      /**
+       * Emits on beginning the application review for the worker/lead opening.
+       * Params:
+       * - Opening id
+       **/
+      BeganApplicationReview: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on setting the leader.
+       * Params:
+       * - Worker id.
+       **/
+      LeaderSet: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on un-setting the leader.
+       * Params:
+       **/
+      LeaderUnset: AugmentedEvent<ApiType, []>;
+      /**
+       * Emits on changing working group mint capacity.
+       * Params:
+       * - mint id.
+       * - new mint balance.
+       **/
+      MintCapacityChanged: AugmentedEvent<ApiType, [MintId, MintBalanceOf]>;
+      /**
+       * Emits on adding new worker opening.
+       * Params:
+       * - Opening id
+       **/
+      OpeningAdded: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on filling the worker opening.
+       * Params:
+       * - Worker opening id
+       * - Worker application id to the worker id dictionary
+       **/
+      OpeningFilled: AugmentedEvent<ApiType, [OpeningId, ApplicationIdToWorkerIdMap]>;
+      /**
+       * Emits on decreasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeDecreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on increasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeIncreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on slashing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeSlashed: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on terminating the leader.
+       * Params:
+       * - leader worker id.
+       * - termination rationale text
+       **/
+      TerminatedLeader: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on terminating the worker.
+       * Params:
+       * - worker id.
+       * - termination rationale text
+       **/
+      TerminatedWorker: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on exiting the worker.
+       * Params:
+       * - worker id.
+       * - exit rationale text
+       **/
+      WorkerExited: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on updating the reward account of the worker.
+       * Params:
+       * - Member id of the worker.
+       * - Reward account id of the worker.
+       **/
+      WorkerRewardAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the reward amount of the worker.
+       * Params:
+       * - Id of the worker.
+       **/
+      WorkerRewardAmountUpdated: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on updating the role account of the worker.
+       * Params:
+       * - Id of the worker.
+       * - Role account id of the worker.
+       **/
+      WorkerRoleAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the worker storage role.
+       * Params:
+       * - Id of the worker.
+       * - Raw storage field.
+       **/
+      WorkerStorageUpdated: AugmentedEvent<ApiType, [WorkerId, Bytes]>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Emits on accepting application for the worker opening.
+       * Params:
+       * - Opening id
+       **/
+      AcceptedApplications: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on terminating the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationTerminated: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on withdrawing the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationWithdrawn: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on adding the application for the worker opening.
+       * Params:
+       * - Opening id
+       * - Application id
+       **/
+      AppliedOnOpening: AugmentedEvent<ApiType, [OpeningId, ApplicationId]>;
+      /**
+       * Emits on beginning the application review for the worker/lead opening.
+       * Params:
+       * - Opening id
+       **/
+      BeganApplicationReview: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on setting the leader.
+       * Params:
+       * - Worker id.
+       **/
+      LeaderSet: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on un-setting the leader.
+       * Params:
+       **/
+      LeaderUnset: AugmentedEvent<ApiType, []>;
+      /**
+       * Emits on changing working group mint capacity.
+       * Params:
+       * - mint id.
+       * - new mint balance.
+       **/
+      MintCapacityChanged: AugmentedEvent<ApiType, [MintId, MintBalanceOf]>;
+      /**
+       * Emits on adding new worker opening.
+       * Params:
+       * - Opening id
+       **/
+      OpeningAdded: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on filling the worker opening.
+       * Params:
+       * - Worker opening id
+       * - Worker application id to the worker id dictionary
+       **/
+      OpeningFilled: AugmentedEvent<ApiType, [OpeningId, ApplicationIdToWorkerIdMap]>;
+      /**
+       * Emits on decreasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeDecreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on increasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeIncreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on slashing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeSlashed: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on terminating the leader.
+       * Params:
+       * - leader worker id.
+       * - termination rationale text
+       **/
+      TerminatedLeader: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on terminating the worker.
+       * Params:
+       * - worker id.
+       * - termination rationale text
+       **/
+      TerminatedWorker: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on exiting the worker.
+       * Params:
+       * - worker id.
+       * - exit rationale text
+       **/
+      WorkerExited: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on updating the reward account of the worker.
+       * Params:
+       * - Member id of the worker.
+       * - Reward account id of the worker.
+       **/
+      WorkerRewardAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the reward amount of the worker.
+       * Params:
+       * - Id of the worker.
+       **/
+      WorkerRewardAmountUpdated: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on updating the role account of the worker.
+       * Params:
+       * - Id of the worker.
+       * - Role account id of the worker.
+       **/
+      WorkerRoleAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the worker storage role.
+       * Params:
+       * - Id of the worker.
+       * - Raw storage field.
+       **/
+      WorkerStorageUpdated: AugmentedEvent<ApiType, [WorkerId, Bytes]>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Emits on accepting application for the worker opening.
        * Params:
@@ -950,8 +1210,10 @@ declare module '@polkadot/api/types/events' {
        * Params
        * - dynamic bag ID
        * - optional DynamicBagDeletionPrize instance
+       * - assigned storage buckets' IDs
+       * - assigned distribution buckets' IDs
        **/
-      DynamicBagCreated: AugmentedEvent<ApiType, [DynamicBagId, Option<DynamicBagDeletionPrizeRecord>]>;
+      DynamicBagCreated: AugmentedEvent<ApiType, [DynamicBagId, Option<DynamicBagDeletionPrizeRecord>, BTreeSet<StorageBucketId>, BTreeSet<DistributionBucketId>]>;
       /**
        * Emits on deleting a dynamic bag.
        * Params

+ 127 - 1
types/augment-codec/augment-api-query.ts

@@ -583,7 +583,133 @@ declare module '@polkadot/api/types/storage' {
        **/
       reportsByKindIndex: AugmentedQuery<ApiType, (arg: Kind | string | Uint8Array) => Observable<Bytes>, [Kind]>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Count of active workers.
+       **/
+      activeWorkerCount: AugmentedQuery<ApiType, () => Observable<u32>, []>;
+      /**
+       * Maps identifier to worker application on opening.
+       **/
+      applicationById: AugmentedQuery<ApiType, (arg: ApplicationId | AnyNumber | Uint8Array) => Observable<ApplicationOf>, [ApplicationId]>;
+      /**
+       * The current lead.
+       **/
+      currentLead: AugmentedQuery<ApiType, () => Observable<Option<WorkerId>>, []>;
+      /**
+       * Map member id by hiring application id.
+       * Required by StakingEventsHandler callback call to refund the balance on unstaking.
+       **/
+      memberIdByHiringApplicationId: AugmentedQuery<ApiType, (arg: HiringApplicationId | AnyNumber | Uint8Array) => Observable<MemberId>, [HiringApplicationId]>;
+      /**
+       * The mint currently funding the rewards for this module.
+       **/
+      mint: AugmentedQuery<ApiType, () => Observable<MintId>, []>;
+      /**
+       * Next identifier value for new worker application.
+       **/
+      nextApplicationId: AugmentedQuery<ApiType, () => Observable<ApplicationId>, []>;
+      /**
+       * Next identifier value for new worker opening.
+       **/
+      nextOpeningId: AugmentedQuery<ApiType, () => Observable<OpeningId>, []>;
+      /**
+       * Next identifier for new worker.
+       **/
+      nextWorkerId: AugmentedQuery<ApiType, () => Observable<WorkerId>, []>;
+      /**
+       * Maps identifier to worker opening.
+       **/
+      openingById: AugmentedQuery<ApiType, (arg: OpeningId | AnyNumber | Uint8Array) => Observable<OpeningOf>, [OpeningId]>;
+      /**
+       * Opening human readable text length limits
+       **/
+      openingHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Worker application human readable text length limits
+       **/
+      workerApplicationHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker.
+       **/
+      workerById: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<WorkerOf>, [WorkerId]>;
+      /**
+       * Worker exit rationale text length limits.
+       **/
+      workerExitRationaleText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker storage.
+       **/
+      workerStorage: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<Bytes>, [WorkerId]>;
+      /**
+       * Worker storage size upper bound.
+       **/
+      workerStorageSize: AugmentedQuery<ApiType, () => Observable<u16>, []>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Count of active workers.
+       **/
+      activeWorkerCount: AugmentedQuery<ApiType, () => Observable<u32>, []>;
+      /**
+       * Maps identifier to worker application on opening.
+       **/
+      applicationById: AugmentedQuery<ApiType, (arg: ApplicationId | AnyNumber | Uint8Array) => Observable<ApplicationOf>, [ApplicationId]>;
+      /**
+       * The current lead.
+       **/
+      currentLead: AugmentedQuery<ApiType, () => Observable<Option<WorkerId>>, []>;
+      /**
+       * Map member id by hiring application id.
+       * Required by StakingEventsHandler callback call to refund the balance on unstaking.
+       **/
+      memberIdByHiringApplicationId: AugmentedQuery<ApiType, (arg: HiringApplicationId | AnyNumber | Uint8Array) => Observable<MemberId>, [HiringApplicationId]>;
+      /**
+       * The mint currently funding the rewards for this module.
+       **/
+      mint: AugmentedQuery<ApiType, () => Observable<MintId>, []>;
+      /**
+       * Next identifier value for new worker application.
+       **/
+      nextApplicationId: AugmentedQuery<ApiType, () => Observable<ApplicationId>, []>;
+      /**
+       * Next identifier value for new worker opening.
+       **/
+      nextOpeningId: AugmentedQuery<ApiType, () => Observable<OpeningId>, []>;
+      /**
+       * Next identifier for new worker.
+       **/
+      nextWorkerId: AugmentedQuery<ApiType, () => Observable<WorkerId>, []>;
+      /**
+       * Maps identifier to worker opening.
+       **/
+      openingById: AugmentedQuery<ApiType, (arg: OpeningId | AnyNumber | Uint8Array) => Observable<OpeningOf>, [OpeningId]>;
+      /**
+       * Opening human readable text length limits
+       **/
+      openingHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Worker application human readable text length limits
+       **/
+      workerApplicationHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker.
+       **/
+      workerById: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<WorkerOf>, [WorkerId]>;
+      /**
+       * Worker exit rationale text length limits.
+       **/
+      workerExitRationaleText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker storage.
+       **/
+      workerStorage: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<Bytes>, [WorkerId]>;
+      /**
+       * Worker storage size upper bound.
+       **/
+      workerStorageSize: AugmentedQuery<ApiType, () => Observable<u16>, []>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Count of active workers.
        **/

+ 168 - 6
types/augment-codec/augment-api-tx.ts

@@ -587,7 +587,169 @@ declare module '@polkadot/api/types/submittable' {
     memo: {
       updateMemo: AugmentedSubmittable<(memo: MemoText | string) => SubmittableExtrinsic<ApiType>, [MemoText]>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Begin accepting worker applications to an opening that is active.
+       * Require signed leader origin or the root (to accept applications for the leader position).
+       **/
+      acceptApplications: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Add an opening for a worker role.
+       * Require signed leader origin or the root (to add opening for the leader position).
+       **/
+      addOpening: AugmentedSubmittable<(activateAt: ActivateOpeningAt | { CurrentBlock: any } | { ExactBlock: any } | string | Uint8Array, commitment: OpeningPolicyCommitment | { application_rationing_policy?: any; max_review_period_length?: any; application_staking_policy?: any; role_staking_policy?: any; role_slashing_terms?: any; fill_opening_successful_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_role_stake_unstaking_period?: any; terminate_application_stake_unstaking_period?: any; terminate_role_stake_unstaking_period?: any; exit_role_application_stake_unstaking_period?: any; exit_role_stake_unstaking_period?: any } | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array, openingType: OpeningType | 'Leader' | 'Worker' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [ActivateOpeningAt, OpeningPolicyCommitment, Bytes, OpeningType]>;
+      /**
+       * Apply on a worker opening.
+       **/
+      applyOnOpening: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, roleAccountId: AccountId | string | Uint8Array, optRoleStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, optApplicationStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, OpeningId, AccountId, Option<BalanceOf>, Option<BalanceOf>, Bytes]>;
+      /**
+       * Begin reviewing, and therefore not accepting new applications.
+       * Require signed leader origin or the root (to begin review applications for the leader position).
+       **/
+      beginApplicantReview: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Decreases the worker/lead stake and returns the remainder to the worker role_account_id.
+       * Can be decreased to zero, no actions on zero stake.
+       * Require signed leader origin or the root (to decrease the leader stake).
+       **/
+      decreaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Fill opening for worker/lead.
+       * Require signed leader origin or the root (to fill opening for the leader position).
+       **/
+      fillOpening: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array, successfulApplicationIds: ApplicationIdSet, rewardPolicy: Option<RewardPolicy> | null | object | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId, ApplicationIdSet, Option<RewardPolicy>]>;
+      /**
+       * Increases the worker/lead stake, demands a worker origin. Transfers tokens from the worker
+       * role_account_id to the stake. No limits on the stake.
+       **/
+      increaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Leave the role by the active worker.
+       **/
+      leaveRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Sets the capacity to enable working group budget. Requires root origin.
+       **/
+      setMintCapacity: AugmentedSubmittable<(newCapacity: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [BalanceOf]>;
+      /**
+       * Slashes the worker stake, demands a leader origin. No limits, no actions on zero stake.
+       * If slashing balance greater than the existing stake - stake is slashed to zero.
+       * Require signed leader origin or the root (to slash the leader stake).
+       **/
+      slashStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Terminate the worker application. Can be done by the lead only.
+       **/
+      terminateApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+      /**
+       * Terminate the active worker by the lead.
+       * Require signed leader origin or the root (to terminate the leader role).
+       **/
+      terminateRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array, slashStake: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes, bool]>;
+      /**
+       * Update the reward account associated with a set reward relationship for the active worker.
+       **/
+      updateRewardAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRewardAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the reward amount associated with a set reward relationship for the active worker.
+       * Require signed leader origin or the root (to update leader reward amount).
+       **/
+      updateRewardAmount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newAmount: BalanceOfMint | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOfMint]>;
+      /**
+       * Update the associated role account of the active worker/lead.
+       **/
+      updateRoleAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRoleAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the associated role storage.
+       **/
+      updateRoleStorage: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, storage: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Withdraw the worker application. Can be done by the worker itself only.
+       **/
+      withdrawApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Begin accepting worker applications to an opening that is active.
+       * Require signed leader origin or the root (to accept applications for the leader position).
+       **/
+      acceptApplications: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Add an opening for a worker role.
+       * Require signed leader origin or the root (to add opening for the leader position).
+       **/
+      addOpening: AugmentedSubmittable<(activateAt: ActivateOpeningAt | { CurrentBlock: any } | { ExactBlock: any } | string | Uint8Array, commitment: OpeningPolicyCommitment | { application_rationing_policy?: any; max_review_period_length?: any; application_staking_policy?: any; role_staking_policy?: any; role_slashing_terms?: any; fill_opening_successful_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_role_stake_unstaking_period?: any; terminate_application_stake_unstaking_period?: any; terminate_role_stake_unstaking_period?: any; exit_role_application_stake_unstaking_period?: any; exit_role_stake_unstaking_period?: any } | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array, openingType: OpeningType | 'Leader' | 'Worker' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [ActivateOpeningAt, OpeningPolicyCommitment, Bytes, OpeningType]>;
+      /**
+       * Apply on a worker opening.
+       **/
+      applyOnOpening: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, roleAccountId: AccountId | string | Uint8Array, optRoleStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, optApplicationStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, OpeningId, AccountId, Option<BalanceOf>, Option<BalanceOf>, Bytes]>;
+      /**
+       * Begin reviewing, and therefore not accepting new applications.
+       * Require signed leader origin or the root (to begin review applications for the leader position).
+       **/
+      beginApplicantReview: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Decreases the worker/lead stake and returns the remainder to the worker role_account_id.
+       * Can be decreased to zero, no actions on zero stake.
+       * Require signed leader origin or the root (to decrease the leader stake).
+       **/
+      decreaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Fill opening for worker/lead.
+       * Require signed leader origin or the root (to fill opening for the leader position).
+       **/
+      fillOpening: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array, successfulApplicationIds: ApplicationIdSet, rewardPolicy: Option<RewardPolicy> | null | object | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId, ApplicationIdSet, Option<RewardPolicy>]>;
+      /**
+       * Increases the worker/lead stake, demands a worker origin. Transfers tokens from the worker
+       * role_account_id to the stake. No limits on the stake.
+       **/
+      increaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Leave the role by the active worker.
+       **/
+      leaveRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Sets the capacity to enable working group budget. Requires root origin.
+       **/
+      setMintCapacity: AugmentedSubmittable<(newCapacity: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [BalanceOf]>;
+      /**
+       * Slashes the worker stake, demands a leader origin. No limits, no actions on zero stake.
+       * If slashing balance greater than the existing stake - stake is slashed to zero.
+       * Require signed leader origin or the root (to slash the leader stake).
+       **/
+      slashStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Terminate the worker application. Can be done by the lead only.
+       **/
+      terminateApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+      /**
+       * Terminate the active worker by the lead.
+       * Require signed leader origin or the root (to terminate the leader role).
+       **/
+      terminateRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array, slashStake: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes, bool]>;
+      /**
+       * Update the reward account associated with a set reward relationship for the active worker.
+       **/
+      updateRewardAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRewardAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the reward amount associated with a set reward relationship for the active worker.
+       * Require signed leader origin or the root (to update leader reward amount).
+       **/
+      updateRewardAmount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newAmount: BalanceOfMint | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOfMint]>;
+      /**
+       * Update the associated role account of the active worker/lead.
+       **/
+      updateRoleAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRoleAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the associated role storage.
+       **/
+      updateRoleStorage: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, storage: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Withdraw the worker application. Can be done by the worker itself only.
+       **/
+      withdrawApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Begin accepting worker applications to an opening that is active.
        * Require signed leader origin or the root (to accept applications for the leader position).
@@ -678,12 +840,12 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'Begin review working group leader applications' proposal type.
        * This proposal uses `begin_applicant_review()` extrinsic from the Joystream `working group` module.
        **/
-      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
+      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
       /**
        * Create 'decrease working group leader stake' proposal type.
        * This proposal uses `decrease_stake()` extrinsic from the `working-group`  module.
        **/
-      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Fill working group leader opening' proposal type.
        * This proposal uses `fill_opening()` extrinsic from the Joystream `working group` module.
@@ -708,17 +870,17 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'set working group leader reward' proposal type.
        * This proposal uses `update_reward_amount()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'Set working group mint capacity' proposal type.
        * This proposal uses `set_mint_capacity()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'slash working group leader stake' proposal type.
        * This proposal uses `slash_stake()` extrinsic from the `working-group`  module.
        **/
-      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Spending' proposal type.
        * This proposal uses `spend_from_council_mint()` extrinsic from the `governance::council`  module.

File diff suppressed because it is too large
+ 0 - 0
types/augment-codec/augment-types.ts


+ 4 - 3
types/augment/all/defs.json

@@ -86,9 +86,11 @@
             "_Reserved1",
             "Storage",
             "Content",
-            "Operations",
+            "OperationsAlpha",
             "Gateway",
-            "Distribution"
+            "Distribution",
+            "OperationsBeta",
+            "OperationsGamma"
         ]
     },
     "SlashingTerms": {
@@ -105,7 +107,6 @@
     "Address": "AccountId",
     "LookupSource": "AccountId",
     "ChannelId": "u64",
-    "DAOId": "u64",
     "Url": "Text",
     "EntryMethod": {
         "_enum": {

+ 3 - 4
types/augment/all/types.ts

@@ -363,9 +363,6 @@ export interface CuratorOpening extends Null {}
 /** @name CuratorOpeningId */
 export interface CuratorOpeningId extends Null {}
 
-/** @name DAOId */
-export interface DAOId extends u64 {}
-
 /** @name DataObject */
 export interface DataObject extends Struct {
   readonly accepted: bool;
@@ -1413,9 +1410,11 @@ export interface WorkingGroup extends Enum {
   readonly isReserved1: boolean;
   readonly isStorage: boolean;
   readonly isContent: boolean;
-  readonly isOperations: boolean;
+  readonly isOperationsAlpha: boolean;
   readonly isGateway: boolean;
   readonly isDistribution: boolean;
+  readonly isOperationsBeta: boolean;
+  readonly isOperationsGamma: boolean;
 }
 
 /** @name WorkingGroupUnstaker */

+ 13 - 1
types/augment/augment-api-consts.ts

@@ -69,7 +69,19 @@ declare module '@polkadot/api/types/consts' {
     members: {
       screenedMemberMaxInitialBalance: BalanceOf & AugmentedConst<ApiType>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Exports const -  max simultaneous active worker number.
+       **/
+      maxWorkerNumberLimit: u32 & AugmentedConst<ApiType>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Exports const -  max simultaneous active worker number.
+       **/
+      maxWorkerNumberLimit: u32 & AugmentedConst<ApiType>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Exports const -  max simultaneous active worker number.
        **/

+ 797 - 1
types/augment/augment-api-errors.ts

@@ -1475,7 +1475,803 @@ declare module '@polkadot/api/types/errors' {
        **/
       UnsignedOrigin: AugmentedError<ApiType>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Opening does not exist.
+       **/
+      AcceptWorkerApplicationsOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting to begin.
+       **/
+      AcceptWorkerApplicationsOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Opening does not activate in the future.
+       **/
+      AddWorkerOpeningActivatesInThePast: AugmentedError<ApiType>;
+      /**
+       * Add worker opening application stake cannot be zero.
+       **/
+      AddWorkerOpeningApplicationStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Application stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningAppliicationStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * New application was crowded out.
+       **/
+      AddWorkerOpeningNewApplicationWasCrowdedOut: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      AddWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening is not in accepting applications stage.
+       **/
+      AddWorkerOpeningOpeningNotInAcceptingApplicationStage: AugmentedError<ApiType>;
+      /**
+       * Add worker opening role stake cannot be zero.
+       **/
+      AddWorkerOpeningRoleStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Role stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningRoleStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * Stake amount too low.
+       **/
+      AddWorkerOpeningStakeAmountTooLow: AugmentedError<ApiType>;
+      /**
+       * Stake missing when required.
+       **/
+      AddWorkerOpeningStakeMissingWhenRequired: AugmentedError<ApiType>;
+      /**
+       * Stake provided when redundant.
+       **/
+      AddWorkerOpeningStakeProvidedWhenRedundant: AugmentedError<ApiType>;
+      /**
+       * Application rationing has zero max active applicants.
+       **/
+      AddWorkerOpeningZeroMaxApplicantCount: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_rationing_policy):
+       * max_active_applicants should be non-zero.
+       **/
+      ApplicationRationingPolicyMaxActiveApplicantsIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer does not match controller account.
+       **/
+      ApplyOnWorkerOpeningSignerNotControllerAccount: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      BeginWorkerApplicantReviewOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting.
+       **/
+      BeginWorkerApplicantReviewOpeningOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Cannot find mint in the minting module.
+       **/
+      CannotFindMint: AugmentedError<ApiType>;
+      /**
+       * There is leader already, cannot hire another one.
+       **/
+      CannotHireLeaderWhenLeaderExists: AugmentedError<ApiType>;
+      /**
+       * Cannot fill opening with multiple applications.
+       **/
+      CannotHireMultipleLeaders: AugmentedError<ApiType>;
+      /**
+       * Current lead is not set.
+       **/
+      CurrentLeadNotSet: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_application_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_role_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Reward policy has invalid next payment block number.
+       **/
+      FillOpeningInvalidNextPaymentBlock: AugmentedError<ApiType>;
+      /**
+       * Working group mint does not exist.
+       **/
+      FillOpeningMintDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_successful_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningSuccessfulApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Applications not for opening.
+       **/
+      FillWorkerOpeningApplicationForWrongOpening: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      FullWorkerOpeningApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application not in active stage.
+       **/
+      FullWorkerOpeningApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * OpeningDoesNotExist.
+       **/
+      FullWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening not in review period stage.
+       **/
+      FullWorkerOpeningOpeningNotInReviewPeriodStage: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to apply.
+       **/
+      InsufficientBalanceToApply: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to cover stake.
+       **/
+      InsufficientBalanceToCoverStake: AugmentedError<ApiType>;
+      /**
+       * Not a lead account.
+       **/
+      IsNotLeadAccount: AugmentedError<ApiType>;
+      /**
+       * Working group size limit exceeded.
+       **/
+      MaxActiveWorkerNumberExceeded: AugmentedError<ApiType>;
+      /**
+       * Member already has an active application on the opening.
+       **/
+      MemberHasActiveApplicationOnOpening: AugmentedError<ApiType>;
+      /**
+       * Member id is invalid.
+       **/
+      MembershipInvalidMemberId: AugmentedError<ApiType>;
+      /**
+       * Unsigned origin.
+       **/
+      MembershipUnsignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Minting error: NextAdjustmentInPast
+       **/
+      MintingErrorNextAdjustmentInPast: AugmentedError<ApiType>;
+      /**
+       * Cannot get the worker stake profile.
+       **/
+      NoWorkerStakeProfile: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      OpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening text too long.
+       **/
+      OpeningTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Opening text too short.
+       **/
+      OpeningTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Origin must be controller or root account of member.
+       **/
+      OriginIsNeitherMemberControllerOrRoot: AugmentedError<ApiType>;
+      /**
+       * Origin is not applicant.
+       **/
+      OriginIsNotApplicant: AugmentedError<ApiType>;
+      /**
+       * Next payment is not in the future.
+       **/
+      RecurringRewardsNextPaymentNotInFuture: AugmentedError<ApiType>;
+      /**
+       * Recipient not found.
+       **/
+      RecurringRewardsRecipientNotFound: AugmentedError<ApiType>;
+      /**
+       * Reward relationship not found.
+       **/
+      RecurringRewardsRewardRelationshipNotFound: AugmentedError<ApiType>;
+      /**
+       * Recipient reward source not found.
+       **/
+      RecurringRewardsRewardSourceNotFound: AugmentedError<ApiType>;
+      /**
+       * Relationship must exist.
+       **/
+      RelationshipMustExist: AugmentedError<ApiType>;
+      /**
+       * Require root origin in extrinsics.
+       **/
+      RequireRootOrigin: AugmentedError<ApiType>;
+      /**
+       * Require signed origin in extrinsics.
+       **/
+      RequireSignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer is not worker role account.
+       **/
+      SignerIsNotWorkerRoleAccount: AugmentedError<ApiType>;
+      /**
+       * Provided stake balance cannot be zero.
+       **/
+      StakeBalanceCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Already unstaking.
+       **/
+      StakingErrorAlreadyUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot change stake by zero.
+       **/
+      StakingErrorCannotChangeStakeByZero: AugmentedError<ApiType>;
+      /**
+       * Cannot decrease stake while slashes ongoing.
+       **/
+      StakingErrorCannotDecreaseWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Cannot increase stake while unstaking.
+       **/
+      StakingErrorCannotIncreaseStakeWhileUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot unstake while slashes ongoing.
+       **/
+      StakingErrorCannotUnstakeWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance in source account.
+       **/
+      StakingErrorInsufficientBalanceInSourceAccount: AugmentedError<ApiType>;
+      /**
+       * Insufficient stake to decrease.
+       **/
+      StakingErrorInsufficientStake: AugmentedError<ApiType>;
+      /**
+       * Not staked.
+       **/
+      StakingErrorNotStaked: AugmentedError<ApiType>;
+      /**
+       * Slash amount should be greater than zero.
+       **/
+      StakingErrorSlashAmountShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Stake not found.
+       **/
+      StakingErrorStakeNotFound: AugmentedError<ApiType>;
+      /**
+       * Unstaking period should be greater than zero.
+       **/
+      StakingErrorUnstakingPeriodShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Successful worker application does not exist.
+       **/
+      SuccessfulWorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_application_stake_unstaking_period should be non-zero.
+       **/
+      TerminateApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_role_stake_unstaking_period should be non-zero.
+       **/
+      TerminateRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      WithdrawWorkerApplicationApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application is not active.
+       **/
+      WithdrawWorkerApplicationApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * Opening not accepting applications.
+       **/
+      WithdrawWorkerApplicationOpeningNotAcceptingApplications: AugmentedError<ApiType>;
+      /**
+       * Redundant unstaking period provided
+       **/
+      WithdrawWorkerApplicationRedundantUnstakingPeriod: AugmentedError<ApiType>;
+      /**
+       * UnstakingPeriodTooShort .... // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
+       **/
+      WithdrawWorkerApplicationUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker application does not exist.
+       **/
+      WorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker application text too long.
+       **/
+      WorkerApplicationTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker application text too short.
+       **/
+      WorkerApplicationTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker does not exist.
+       **/
+      WorkerDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too long.
+       **/
+      WorkerExitRationaleTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too short.
+       **/
+      WorkerExitRationaleTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker has no recurring reward.
+       **/
+      WorkerHasNoReward: AugmentedError<ApiType>;
+      /**
+       * Worker storage text is too long.
+       **/
+      WorkerStorageValueTooLong: AugmentedError<ApiType>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Opening does not exist.
+       **/
+      AcceptWorkerApplicationsOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting to begin.
+       **/
+      AcceptWorkerApplicationsOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Opening does not activate in the future.
+       **/
+      AddWorkerOpeningActivatesInThePast: AugmentedError<ApiType>;
+      /**
+       * Add worker opening application stake cannot be zero.
+       **/
+      AddWorkerOpeningApplicationStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Application stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningAppliicationStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * New application was crowded out.
+       **/
+      AddWorkerOpeningNewApplicationWasCrowdedOut: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      AddWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening is not in accepting applications stage.
+       **/
+      AddWorkerOpeningOpeningNotInAcceptingApplicationStage: AugmentedError<ApiType>;
+      /**
+       * Add worker opening role stake cannot be zero.
+       **/
+      AddWorkerOpeningRoleStakeCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Role stake amount less than minimum currency balance.
+       **/
+      AddWorkerOpeningRoleStakeLessThanMinimum: AugmentedError<ApiType>;
+      /**
+       * Stake amount too low.
+       **/
+      AddWorkerOpeningStakeAmountTooLow: AugmentedError<ApiType>;
+      /**
+       * Stake missing when required.
+       **/
+      AddWorkerOpeningStakeMissingWhenRequired: AugmentedError<ApiType>;
+      /**
+       * Stake provided when redundant.
+       **/
+      AddWorkerOpeningStakeProvidedWhenRedundant: AugmentedError<ApiType>;
+      /**
+       * Application rationing has zero max active applicants.
+       **/
+      AddWorkerOpeningZeroMaxApplicantCount: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_rationing_policy):
+       * max_active_applicants should be non-zero.
+       **/
+      ApplicationRationingPolicyMaxActiveApplicantsIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (application_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      ApplicationStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer does not match controller account.
+       **/
+      ApplyOnWorkerOpeningSignerNotControllerAccount: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      BeginWorkerApplicantReviewOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening Is Not in Waiting.
+       **/
+      BeginWorkerApplicantReviewOpeningOpeningIsNotWaitingToBegin: AugmentedError<ApiType>;
+      /**
+       * Cannot find mint in the minting module.
+       **/
+      CannotFindMint: AugmentedError<ApiType>;
+      /**
+       * There is leader already, cannot hire another one.
+       **/
+      CannotHireLeaderWhenLeaderExists: AugmentedError<ApiType>;
+      /**
+       * Cannot fill opening with multiple applications.
+       **/
+      CannotHireMultipleLeaders: AugmentedError<ApiType>;
+      /**
+       * Current lead is not set.
+       **/
+      CurrentLeadNotSet: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_application_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * exit_role_stake_unstaking_period should be non-zero.
+       **/
+      ExitRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_failed_applicant_role_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningFailedApplicantRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Reward policy has invalid next payment block number.
+       **/
+      FillOpeningInvalidNextPaymentBlock: AugmentedError<ApiType>;
+      /**
+       * Working group mint does not exist.
+       **/
+      FillOpeningMintDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * fill_opening_successful_applicant_application_stake_unstaking_period should be non-zero.
+       **/
+      FillOpeningSuccessfulApplicantApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Applications not for opening.
+       **/
+      FillWorkerOpeningApplicationForWrongOpening: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      FullWorkerOpeningApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application not in active stage.
+       **/
+      FullWorkerOpeningApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * OpeningDoesNotExist.
+       **/
+      FullWorkerOpeningOpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening not in review period stage.
+       **/
+      FullWorkerOpeningOpeningNotInReviewPeriodStage: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants redundant.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Application stake unstaking period for successful applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants redundant.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodRedundant: AugmentedError<ApiType>;
+      /**
+       * Role stake unstaking period for failed applicants too short.
+       **/
+      FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to apply.
+       **/
+      InsufficientBalanceToApply: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance to cover stake.
+       **/
+      InsufficientBalanceToCoverStake: AugmentedError<ApiType>;
+      /**
+       * Not a lead account.
+       **/
+      IsNotLeadAccount: AugmentedError<ApiType>;
+      /**
+       * Working group size limit exceeded.
+       **/
+      MaxActiveWorkerNumberExceeded: AugmentedError<ApiType>;
+      /**
+       * Member already has an active application on the opening.
+       **/
+      MemberHasActiveApplicationOnOpening: AugmentedError<ApiType>;
+      /**
+       * Member id is invalid.
+       **/
+      MembershipInvalidMemberId: AugmentedError<ApiType>;
+      /**
+       * Unsigned origin.
+       **/
+      MembershipUnsignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Minting error: NextAdjustmentInPast
+       **/
+      MintingErrorNextAdjustmentInPast: AugmentedError<ApiType>;
+      /**
+       * Cannot get the worker stake profile.
+       **/
+      NoWorkerStakeProfile: AugmentedError<ApiType>;
+      /**
+       * Opening does not exist.
+       **/
+      OpeningDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Opening text too long.
+       **/
+      OpeningTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Opening text too short.
+       **/
+      OpeningTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Origin must be controller or root account of member.
+       **/
+      OriginIsNeitherMemberControllerOrRoot: AugmentedError<ApiType>;
+      /**
+       * Origin is not applicant.
+       **/
+      OriginIsNotApplicant: AugmentedError<ApiType>;
+      /**
+       * Next payment is not in the future.
+       **/
+      RecurringRewardsNextPaymentNotInFuture: AugmentedError<ApiType>;
+      /**
+       * Recipient not found.
+       **/
+      RecurringRewardsRecipientNotFound: AugmentedError<ApiType>;
+      /**
+       * Reward relationship not found.
+       **/
+      RecurringRewardsRewardRelationshipNotFound: AugmentedError<ApiType>;
+      /**
+       * Recipient reward source not found.
+       **/
+      RecurringRewardsRewardSourceNotFound: AugmentedError<ApiType>;
+      /**
+       * Relationship must exist.
+       **/
+      RelationshipMustExist: AugmentedError<ApiType>;
+      /**
+       * Require root origin in extrinsics.
+       **/
+      RequireRootOrigin: AugmentedError<ApiType>;
+      /**
+       * Require signed origin in extrinsics.
+       **/
+      RequireSignedOrigin: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * crowded_out_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyCrowdedOutUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter (role_staking_policy):
+       * review_period_expired_unstaking_period_length should be non-zero.
+       **/
+      RoleStakingPolicyReviewPeriodUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Signer is not worker role account.
+       **/
+      SignerIsNotWorkerRoleAccount: AugmentedError<ApiType>;
+      /**
+       * Provided stake balance cannot be zero.
+       **/
+      StakeBalanceCannotBeZero: AugmentedError<ApiType>;
+      /**
+       * Already unstaking.
+       **/
+      StakingErrorAlreadyUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot change stake by zero.
+       **/
+      StakingErrorCannotChangeStakeByZero: AugmentedError<ApiType>;
+      /**
+       * Cannot decrease stake while slashes ongoing.
+       **/
+      StakingErrorCannotDecreaseWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Cannot increase stake while unstaking.
+       **/
+      StakingErrorCannotIncreaseStakeWhileUnstaking: AugmentedError<ApiType>;
+      /**
+       * Cannot unstake while slashes ongoing.
+       **/
+      StakingErrorCannotUnstakeWhileSlashesOngoing: AugmentedError<ApiType>;
+      /**
+       * Insufficient balance in source account.
+       **/
+      StakingErrorInsufficientBalanceInSourceAccount: AugmentedError<ApiType>;
+      /**
+       * Insufficient stake to decrease.
+       **/
+      StakingErrorInsufficientStake: AugmentedError<ApiType>;
+      /**
+       * Not staked.
+       **/
+      StakingErrorNotStaked: AugmentedError<ApiType>;
+      /**
+       * Slash amount should be greater than zero.
+       **/
+      StakingErrorSlashAmountShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Stake not found.
+       **/
+      StakingErrorStakeNotFound: AugmentedError<ApiType>;
+      /**
+       * Unstaking period should be greater than zero.
+       **/
+      StakingErrorUnstakingPeriodShouldBeGreaterThanZero: AugmentedError<ApiType>;
+      /**
+       * Successful worker application does not exist.
+       **/
+      SuccessfulWorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_application_stake_unstaking_period should be non-zero.
+       **/
+      TerminateApplicationStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Invalid OpeningPolicyCommitment parameter:
+       * terminate_role_stake_unstaking_period should be non-zero.
+       **/
+      TerminateRoleStakeUnstakingPeriodIsZero: AugmentedError<ApiType>;
+      /**
+       * Application does not exist.
+       **/
+      WithdrawWorkerApplicationApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Application is not active.
+       **/
+      WithdrawWorkerApplicationApplicationNotActive: AugmentedError<ApiType>;
+      /**
+       * Opening not accepting applications.
+       **/
+      WithdrawWorkerApplicationOpeningNotAcceptingApplications: AugmentedError<ApiType>;
+      /**
+       * Redundant unstaking period provided
+       **/
+      WithdrawWorkerApplicationRedundantUnstakingPeriod: AugmentedError<ApiType>;
+      /**
+       * UnstakingPeriodTooShort .... // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
+       **/
+      WithdrawWorkerApplicationUnstakingPeriodTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker application does not exist.
+       **/
+      WorkerApplicationDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker application text too long.
+       **/
+      WorkerApplicationTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker application text too short.
+       **/
+      WorkerApplicationTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker does not exist.
+       **/
+      WorkerDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too long.
+       **/
+      WorkerExitRationaleTextTooLong: AugmentedError<ApiType>;
+      /**
+       * Worker exit rationale text is too short.
+       **/
+      WorkerExitRationaleTextTooShort: AugmentedError<ApiType>;
+      /**
+       * Worker has no recurring reward.
+       **/
+      WorkerHasNoReward: AugmentedError<ApiType>;
+      /**
+       * Worker storage text is too long.
+       **/
+      WorkerStorageValueTooLong: AugmentedError<ApiType>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Opening does not exist.
        **/

+ 267 - 5
types/augment/augment-api-events.ts

@@ -565,9 +565,9 @@ declare module '@polkadot/api/types/events' {
       MemberRegistered: AugmentedEvent<ApiType, [MemberId, AccountId, EntryMethod]>;
       MemberSetControllerAccount: AugmentedEvent<ApiType, [MemberId, AccountId]>;
       MemberSetRootAccount: AugmentedEvent<ApiType, [MemberId, AccountId]>;
-      MemberUpdatedAboutText: AugmentedEvent<ApiType, [MemberId]>;
-      MemberUpdatedAvatar: AugmentedEvent<ApiType, [MemberId]>;
-      MemberUpdatedHandle: AugmentedEvent<ApiType, [MemberId]>;
+      MemberUpdatedAboutText: AugmentedEvent<ApiType, [MemberId, Bytes]>;
+      MemberUpdatedAvatar: AugmentedEvent<ApiType, [MemberId, Bytes]>;
+      MemberUpdatedHandle: AugmentedEvent<ApiType, [MemberId, Bytes]>;
     };
     memo: {
       MemoUpdated: AugmentedEvent<ApiType, [AccountId]>;
@@ -581,7 +581,267 @@ declare module '@polkadot/api/types/events' {
        **/
       Offence: AugmentedEvent<ApiType, [Kind, OpaqueTimeSlot, bool]>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Emits on accepting application for the worker opening.
+       * Params:
+       * - Opening id
+       **/
+      AcceptedApplications: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on terminating the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationTerminated: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on withdrawing the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationWithdrawn: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on adding the application for the worker opening.
+       * Params:
+       * - Opening id
+       * - Application id
+       **/
+      AppliedOnOpening: AugmentedEvent<ApiType, [OpeningId, ApplicationId]>;
+      /**
+       * Emits on beginning the application review for the worker/lead opening.
+       * Params:
+       * - Opening id
+       **/
+      BeganApplicationReview: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on setting the leader.
+       * Params:
+       * - Worker id.
+       **/
+      LeaderSet: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on un-setting the leader.
+       * Params:
+       **/
+      LeaderUnset: AugmentedEvent<ApiType, []>;
+      /**
+       * Emits on changing working group mint capacity.
+       * Params:
+       * - mint id.
+       * - new mint balance.
+       **/
+      MintCapacityChanged: AugmentedEvent<ApiType, [MintId, MintBalanceOf]>;
+      /**
+       * Emits on adding new worker opening.
+       * Params:
+       * - Opening id
+       **/
+      OpeningAdded: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on filling the worker opening.
+       * Params:
+       * - Worker opening id
+       * - Worker application id to the worker id dictionary
+       **/
+      OpeningFilled: AugmentedEvent<ApiType, [OpeningId, ApplicationIdToWorkerIdMap]>;
+      /**
+       * Emits on decreasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeDecreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on increasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeIncreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on slashing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeSlashed: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on terminating the leader.
+       * Params:
+       * - leader worker id.
+       * - termination rationale text
+       **/
+      TerminatedLeader: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on terminating the worker.
+       * Params:
+       * - worker id.
+       * - termination rationale text
+       **/
+      TerminatedWorker: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on exiting the worker.
+       * Params:
+       * - worker id.
+       * - exit rationale text
+       **/
+      WorkerExited: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on updating the reward account of the worker.
+       * Params:
+       * - Member id of the worker.
+       * - Reward account id of the worker.
+       **/
+      WorkerRewardAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the reward amount of the worker.
+       * Params:
+       * - Id of the worker.
+       **/
+      WorkerRewardAmountUpdated: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on updating the role account of the worker.
+       * Params:
+       * - Id of the worker.
+       * - Role account id of the worker.
+       **/
+      WorkerRoleAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the worker storage role.
+       * Params:
+       * - Id of the worker.
+       * - Raw storage field.
+       **/
+      WorkerStorageUpdated: AugmentedEvent<ApiType, [WorkerId, Bytes]>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Emits on accepting application for the worker opening.
+       * Params:
+       * - Opening id
+       **/
+      AcceptedApplications: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on terminating the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationTerminated: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on withdrawing the application for the worker/lead opening.
+       * Params:
+       * - Worker application id
+       **/
+      ApplicationWithdrawn: AugmentedEvent<ApiType, [ApplicationId]>;
+      /**
+       * Emits on adding the application for the worker opening.
+       * Params:
+       * - Opening id
+       * - Application id
+       **/
+      AppliedOnOpening: AugmentedEvent<ApiType, [OpeningId, ApplicationId]>;
+      /**
+       * Emits on beginning the application review for the worker/lead opening.
+       * Params:
+       * - Opening id
+       **/
+      BeganApplicationReview: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on setting the leader.
+       * Params:
+       * - Worker id.
+       **/
+      LeaderSet: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on un-setting the leader.
+       * Params:
+       **/
+      LeaderUnset: AugmentedEvent<ApiType, []>;
+      /**
+       * Emits on changing working group mint capacity.
+       * Params:
+       * - mint id.
+       * - new mint balance.
+       **/
+      MintCapacityChanged: AugmentedEvent<ApiType, [MintId, MintBalanceOf]>;
+      /**
+       * Emits on adding new worker opening.
+       * Params:
+       * - Opening id
+       **/
+      OpeningAdded: AugmentedEvent<ApiType, [OpeningId]>;
+      /**
+       * Emits on filling the worker opening.
+       * Params:
+       * - Worker opening id
+       * - Worker application id to the worker id dictionary
+       **/
+      OpeningFilled: AugmentedEvent<ApiType, [OpeningId, ApplicationIdToWorkerIdMap]>;
+      /**
+       * Emits on decreasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeDecreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on increasing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeIncreased: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on slashing the worker/lead stake.
+       * Params:
+       * - worker/lead id.
+       **/
+      StakeSlashed: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on terminating the leader.
+       * Params:
+       * - leader worker id.
+       * - termination rationale text
+       **/
+      TerminatedLeader: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on terminating the worker.
+       * Params:
+       * - worker id.
+       * - termination rationale text
+       **/
+      TerminatedWorker: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on exiting the worker.
+       * Params:
+       * - worker id.
+       * - exit rationale text
+       **/
+      WorkerExited: AugmentedEvent<ApiType, [WorkerId, RationaleText]>;
+      /**
+       * Emits on updating the reward account of the worker.
+       * Params:
+       * - Member id of the worker.
+       * - Reward account id of the worker.
+       **/
+      WorkerRewardAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the reward amount of the worker.
+       * Params:
+       * - Id of the worker.
+       **/
+      WorkerRewardAmountUpdated: AugmentedEvent<ApiType, [WorkerId]>;
+      /**
+       * Emits on updating the role account of the worker.
+       * Params:
+       * - Id of the worker.
+       * - Role account id of the worker.
+       **/
+      WorkerRoleAccountUpdated: AugmentedEvent<ApiType, [WorkerId, AccountId]>;
+      /**
+       * Emits on updating the worker storage role.
+       * Params:
+       * - Id of the worker.
+       * - Raw storage field.
+       **/
+      WorkerStorageUpdated: AugmentedEvent<ApiType, [WorkerId, Bytes]>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Emits on accepting application for the worker opening.
        * Params:
@@ -950,8 +1210,10 @@ declare module '@polkadot/api/types/events' {
        * Params
        * - dynamic bag ID
        * - optional DynamicBagDeletionPrize instance
+       * - assigned storage buckets' IDs
+       * - assigned distribution buckets' IDs
        **/
-      DynamicBagCreated: AugmentedEvent<ApiType, [DynamicBagId, Option<DynamicBagDeletionPrizeRecord>]>;
+      DynamicBagCreated: AugmentedEvent<ApiType, [DynamicBagId, Option<DynamicBagDeletionPrizeRecord>, BTreeSet<StorageBucketId>, BTreeSet<DistributionBucketId>]>;
       /**
        * Emits on deleting a dynamic bag.
        * Params

+ 127 - 1
types/augment/augment-api-query.ts

@@ -583,7 +583,133 @@ declare module '@polkadot/api/types/storage' {
        **/
       reportsByKindIndex: AugmentedQuery<ApiType, (arg: Kind | string | Uint8Array) => Observable<Bytes>, [Kind]>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Count of active workers.
+       **/
+      activeWorkerCount: AugmentedQuery<ApiType, () => Observable<u32>, []>;
+      /**
+       * Maps identifier to worker application on opening.
+       **/
+      applicationById: AugmentedQuery<ApiType, (arg: ApplicationId | AnyNumber | Uint8Array) => Observable<ApplicationOf>, [ApplicationId]>;
+      /**
+       * The current lead.
+       **/
+      currentLead: AugmentedQuery<ApiType, () => Observable<Option<WorkerId>>, []>;
+      /**
+       * Map member id by hiring application id.
+       * Required by StakingEventsHandler callback call to refund the balance on unstaking.
+       **/
+      memberIdByHiringApplicationId: AugmentedQuery<ApiType, (arg: HiringApplicationId | AnyNumber | Uint8Array) => Observable<MemberId>, [HiringApplicationId]>;
+      /**
+       * The mint currently funding the rewards for this module.
+       **/
+      mint: AugmentedQuery<ApiType, () => Observable<MintId>, []>;
+      /**
+       * Next identifier value for new worker application.
+       **/
+      nextApplicationId: AugmentedQuery<ApiType, () => Observable<ApplicationId>, []>;
+      /**
+       * Next identifier value for new worker opening.
+       **/
+      nextOpeningId: AugmentedQuery<ApiType, () => Observable<OpeningId>, []>;
+      /**
+       * Next identifier for new worker.
+       **/
+      nextWorkerId: AugmentedQuery<ApiType, () => Observable<WorkerId>, []>;
+      /**
+       * Maps identifier to worker opening.
+       **/
+      openingById: AugmentedQuery<ApiType, (arg: OpeningId | AnyNumber | Uint8Array) => Observable<OpeningOf>, [OpeningId]>;
+      /**
+       * Opening human readable text length limits
+       **/
+      openingHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Worker application human readable text length limits
+       **/
+      workerApplicationHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker.
+       **/
+      workerById: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<WorkerOf>, [WorkerId]>;
+      /**
+       * Worker exit rationale text length limits.
+       **/
+      workerExitRationaleText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker storage.
+       **/
+      workerStorage: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<Bytes>, [WorkerId]>;
+      /**
+       * Worker storage size upper bound.
+       **/
+      workerStorageSize: AugmentedQuery<ApiType, () => Observable<u16>, []>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Count of active workers.
+       **/
+      activeWorkerCount: AugmentedQuery<ApiType, () => Observable<u32>, []>;
+      /**
+       * Maps identifier to worker application on opening.
+       **/
+      applicationById: AugmentedQuery<ApiType, (arg: ApplicationId | AnyNumber | Uint8Array) => Observable<ApplicationOf>, [ApplicationId]>;
+      /**
+       * The current lead.
+       **/
+      currentLead: AugmentedQuery<ApiType, () => Observable<Option<WorkerId>>, []>;
+      /**
+       * Map member id by hiring application id.
+       * Required by StakingEventsHandler callback call to refund the balance on unstaking.
+       **/
+      memberIdByHiringApplicationId: AugmentedQuery<ApiType, (arg: HiringApplicationId | AnyNumber | Uint8Array) => Observable<MemberId>, [HiringApplicationId]>;
+      /**
+       * The mint currently funding the rewards for this module.
+       **/
+      mint: AugmentedQuery<ApiType, () => Observable<MintId>, []>;
+      /**
+       * Next identifier value for new worker application.
+       **/
+      nextApplicationId: AugmentedQuery<ApiType, () => Observable<ApplicationId>, []>;
+      /**
+       * Next identifier value for new worker opening.
+       **/
+      nextOpeningId: AugmentedQuery<ApiType, () => Observable<OpeningId>, []>;
+      /**
+       * Next identifier for new worker.
+       **/
+      nextWorkerId: AugmentedQuery<ApiType, () => Observable<WorkerId>, []>;
+      /**
+       * Maps identifier to worker opening.
+       **/
+      openingById: AugmentedQuery<ApiType, (arg: OpeningId | AnyNumber | Uint8Array) => Observable<OpeningOf>, [OpeningId]>;
+      /**
+       * Opening human readable text length limits
+       **/
+      openingHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Worker application human readable text length limits
+       **/
+      workerApplicationHumanReadableText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker.
+       **/
+      workerById: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<WorkerOf>, [WorkerId]>;
+      /**
+       * Worker exit rationale text length limits.
+       **/
+      workerExitRationaleText: AugmentedQuery<ApiType, () => Observable<InputValidationLengthConstraint>, []>;
+      /**
+       * Maps identifier to corresponding worker storage.
+       **/
+      workerStorage: AugmentedQuery<ApiType, (arg: WorkerId | AnyNumber | Uint8Array) => Observable<Bytes>, [WorkerId]>;
+      /**
+       * Worker storage size upper bound.
+       **/
+      workerStorageSize: AugmentedQuery<ApiType, () => Observable<u16>, []>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Count of active workers.
        **/

+ 168 - 6
types/augment/augment-api-tx.ts

@@ -587,7 +587,169 @@ declare module '@polkadot/api/types/submittable' {
     memo: {
       updateMemo: AugmentedSubmittable<(memo: MemoText | string) => SubmittableExtrinsic<ApiType>, [MemoText]>;
     };
-    operationsWorkingGroup: {
+    operationsWorkingGroupAlpha: {
+      /**
+       * Begin accepting worker applications to an opening that is active.
+       * Require signed leader origin or the root (to accept applications for the leader position).
+       **/
+      acceptApplications: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Add an opening for a worker role.
+       * Require signed leader origin or the root (to add opening for the leader position).
+       **/
+      addOpening: AugmentedSubmittable<(activateAt: ActivateOpeningAt | { CurrentBlock: any } | { ExactBlock: any } | string | Uint8Array, commitment: OpeningPolicyCommitment | { application_rationing_policy?: any; max_review_period_length?: any; application_staking_policy?: any; role_staking_policy?: any; role_slashing_terms?: any; fill_opening_successful_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_role_stake_unstaking_period?: any; terminate_application_stake_unstaking_period?: any; terminate_role_stake_unstaking_period?: any; exit_role_application_stake_unstaking_period?: any; exit_role_stake_unstaking_period?: any } | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array, openingType: OpeningType | 'Leader' | 'Worker' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [ActivateOpeningAt, OpeningPolicyCommitment, Bytes, OpeningType]>;
+      /**
+       * Apply on a worker opening.
+       **/
+      applyOnOpening: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, roleAccountId: AccountId | string | Uint8Array, optRoleStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, optApplicationStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, OpeningId, AccountId, Option<BalanceOf>, Option<BalanceOf>, Bytes]>;
+      /**
+       * Begin reviewing, and therefore not accepting new applications.
+       * Require signed leader origin or the root (to begin review applications for the leader position).
+       **/
+      beginApplicantReview: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Decreases the worker/lead stake and returns the remainder to the worker role_account_id.
+       * Can be decreased to zero, no actions on zero stake.
+       * Require signed leader origin or the root (to decrease the leader stake).
+       **/
+      decreaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Fill opening for worker/lead.
+       * Require signed leader origin or the root (to fill opening for the leader position).
+       **/
+      fillOpening: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array, successfulApplicationIds: ApplicationIdSet, rewardPolicy: Option<RewardPolicy> | null | object | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId, ApplicationIdSet, Option<RewardPolicy>]>;
+      /**
+       * Increases the worker/lead stake, demands a worker origin. Transfers tokens from the worker
+       * role_account_id to the stake. No limits on the stake.
+       **/
+      increaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Leave the role by the active worker.
+       **/
+      leaveRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Sets the capacity to enable working group budget. Requires root origin.
+       **/
+      setMintCapacity: AugmentedSubmittable<(newCapacity: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [BalanceOf]>;
+      /**
+       * Slashes the worker stake, demands a leader origin. No limits, no actions on zero stake.
+       * If slashing balance greater than the existing stake - stake is slashed to zero.
+       * Require signed leader origin or the root (to slash the leader stake).
+       **/
+      slashStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Terminate the worker application. Can be done by the lead only.
+       **/
+      terminateApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+      /**
+       * Terminate the active worker by the lead.
+       * Require signed leader origin or the root (to terminate the leader role).
+       **/
+      terminateRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array, slashStake: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes, bool]>;
+      /**
+       * Update the reward account associated with a set reward relationship for the active worker.
+       **/
+      updateRewardAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRewardAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the reward amount associated with a set reward relationship for the active worker.
+       * Require signed leader origin or the root (to update leader reward amount).
+       **/
+      updateRewardAmount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newAmount: BalanceOfMint | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOfMint]>;
+      /**
+       * Update the associated role account of the active worker/lead.
+       **/
+      updateRoleAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRoleAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the associated role storage.
+       **/
+      updateRoleStorage: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, storage: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Withdraw the worker application. Can be done by the worker itself only.
+       **/
+      withdrawApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+    };
+    operationsWorkingGroupBeta: {
+      /**
+       * Begin accepting worker applications to an opening that is active.
+       * Require signed leader origin or the root (to accept applications for the leader position).
+       **/
+      acceptApplications: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Add an opening for a worker role.
+       * Require signed leader origin or the root (to add opening for the leader position).
+       **/
+      addOpening: AugmentedSubmittable<(activateAt: ActivateOpeningAt | { CurrentBlock: any } | { ExactBlock: any } | string | Uint8Array, commitment: OpeningPolicyCommitment | { application_rationing_policy?: any; max_review_period_length?: any; application_staking_policy?: any; role_staking_policy?: any; role_slashing_terms?: any; fill_opening_successful_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_application_stake_unstaking_period?: any; fill_opening_failed_applicant_role_stake_unstaking_period?: any; terminate_application_stake_unstaking_period?: any; terminate_role_stake_unstaking_period?: any; exit_role_application_stake_unstaking_period?: any; exit_role_stake_unstaking_period?: any } | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array, openingType: OpeningType | 'Leader' | 'Worker' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [ActivateOpeningAt, OpeningPolicyCommitment, Bytes, OpeningType]>;
+      /**
+       * Apply on a worker opening.
+       **/
+      applyOnOpening: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, roleAccountId: AccountId | string | Uint8Array, optRoleStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, optApplicationStakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, humanReadableText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, OpeningId, AccountId, Option<BalanceOf>, Option<BalanceOf>, Bytes]>;
+      /**
+       * Begin reviewing, and therefore not accepting new applications.
+       * Require signed leader origin or the root (to begin review applications for the leader position).
+       **/
+      beginApplicantReview: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId]>;
+      /**
+       * Decreases the worker/lead stake and returns the remainder to the worker role_account_id.
+       * Can be decreased to zero, no actions on zero stake.
+       * Require signed leader origin or the root (to decrease the leader stake).
+       **/
+      decreaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Fill opening for worker/lead.
+       * Require signed leader origin or the root (to fill opening for the leader position).
+       **/
+      fillOpening: AugmentedSubmittable<(openingId: OpeningId | AnyNumber | Uint8Array, successfulApplicationIds: ApplicationIdSet, rewardPolicy: Option<RewardPolicy> | null | object | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [OpeningId, ApplicationIdSet, Option<RewardPolicy>]>;
+      /**
+       * Increases the worker/lead stake, demands a worker origin. Transfers tokens from the worker
+       * role_account_id to the stake. No limits on the stake.
+       **/
+      increaseStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Leave the role by the active worker.
+       **/
+      leaveRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Sets the capacity to enable working group budget. Requires root origin.
+       **/
+      setMintCapacity: AugmentedSubmittable<(newCapacity: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [BalanceOf]>;
+      /**
+       * Slashes the worker stake, demands a leader origin. No limits, no actions on zero stake.
+       * If slashing balance greater than the existing stake - stake is slashed to zero.
+       * Require signed leader origin or the root (to slash the leader stake).
+       **/
+      slashStake: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOf]>;
+      /**
+       * Terminate the worker application. Can be done by the lead only.
+       **/
+      terminateApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+      /**
+       * Terminate the active worker by the lead.
+       * Require signed leader origin or the root (to terminate the leader role).
+       **/
+      terminateRole: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, rationaleText: Bytes | string | Uint8Array, slashStake: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes, bool]>;
+      /**
+       * Update the reward account associated with a set reward relationship for the active worker.
+       **/
+      updateRewardAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRewardAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the reward amount associated with a set reward relationship for the active worker.
+       * Require signed leader origin or the root (to update leader reward amount).
+       **/
+      updateRewardAmount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newAmount: BalanceOfMint | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, BalanceOfMint]>;
+      /**
+       * Update the associated role account of the active worker/lead.
+       **/
+      updateRoleAccount: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, newRoleAccountId: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, AccountId]>;
+      /**
+       * Update the associated role storage.
+       **/
+      updateRoleStorage: AugmentedSubmittable<(workerId: WorkerId | AnyNumber | Uint8Array, storage: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [WorkerId, Bytes]>;
+      /**
+       * Withdraw the worker application. Can be done by the worker itself only.
+       **/
+      withdrawApplication: AugmentedSubmittable<(applicationId: ApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ApplicationId]>;
+    };
+    operationsWorkingGroupGamma: {
       /**
        * Begin accepting worker applications to an opening that is active.
        * Require signed leader origin or the root (to accept applications for the leader position).
@@ -678,12 +840,12 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'Begin review working group leader applications' proposal type.
        * This proposal uses `begin_applicant_review()` extrinsic from the Joystream `working group` module.
        **/
-      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
+      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
       /**
        * Create 'decrease working group leader stake' proposal type.
        * This proposal uses `decrease_stake()` extrinsic from the `working-group`  module.
        **/
-      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Fill working group leader opening' proposal type.
        * This proposal uses `fill_opening()` extrinsic from the Joystream `working group` module.
@@ -708,17 +870,17 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'set working group leader reward' proposal type.
        * This proposal uses `update_reward_amount()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'Set working group mint capacity' proposal type.
        * This proposal uses `set_mint_capacity()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'slash working group leader stake' proposal type.
        * This proposal uses `slash_stake()` extrinsic from the `working-group`  module.
        **/
-      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'OperationsAlpha' | 'Gateway' | 'Distribution' | 'OperationsBeta' | 'OperationsGamma' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Spending' proposal type.
        * This proposal uses `spend_from_council_mint()` extrinsic from the `governance::council`  module.

File diff suppressed because it is too large
+ 0 - 0
types/augment/augment-types.ts


+ 1 - 1
types/src/JoyEnum.ts

@@ -33,7 +33,7 @@ export function JoyEnum<Types extends Record<string, Constructor>>(types: Types)
     }
 
     // eslint-disable-next-line no-useless-constructor
-    constructor(registry: Registry, value?: any, index?: number) {
+    constructor(registry: Registry, value?: unknown, index?: number) {
       super(registry, value, index)
     }
 

+ 9 - 24
types/src/common.ts

@@ -1,7 +1,6 @@
 import { Struct, Option, Text, bool, u16, u32, u64, Null, U8aFixed, BTreeSet, UInt, u128 } from '@polkadot/types'
 import { BlockNumber, Hash as PolkadotHash, Moment } from '@polkadot/types/interfaces'
 import { Codec, Constructor, RegistryTypes } from '@polkadot/types/types'
-import { u8aConcat, u8aToHex, compactToU8a } from '@polkadot/util'
 // we get 'moment' because it is a dependency of @polkadot/util, via @polkadot/keyring
 import moment from 'moment'
 import { JoyStructCustom, JoyStructDecorated } from './JoyStruct'
@@ -16,30 +15,16 @@ export { JoyEnum, JoyStructCustom, JoyStructDecorated }
 export interface ExtendedBTreeSet<V extends UInt> extends BTreeSet<V> {
   toArray(): V[]
 }
+
 export function JoyBTreeSet<V extends UInt>(valType: Constructor<V>): Constructor<ExtendedBTreeSet<V>> {
   return class extends BTreeSet.with(valType) {
-    public toArray(): V[] {
-      return Array.from(this)
-    }
-
-    public toU8a(isBare?: boolean): Uint8Array {
-      const encoded = new Array<Uint8Array>()
-
-      if (!isBare) {
-        encoded.push(compactToU8a(this.size))
-      }
-
-      const sorted = Array.from(this).sort((a, b) => (a.lt(b) ? -1 : 1))
-
-      sorted.forEach((v: V) => {
-        encoded.push(v.toU8a(isBare))
-      })
-
-      return u8aConcat(...encoded)
+    public forEach(callbackFn: (value: V, value2: V, set: Set<V>) => void, thisArg?: unknown): void {
+      const sorted = this.toArray()
+      return new Set(sorted).forEach(callbackFn, thisArg)
     }
 
-    public toHex(): string {
-      return u8aToHex(this.toU8a())
+    public toArray() {
+      return Array.from(this).sort((a, b) => (a.lt(b) ? -1 : 1))
     }
   }
 }
@@ -47,7 +32,6 @@ export function JoyBTreeSet<V extends UInt>(valType: Constructor<V>): Constructo
 export class Url extends Text {}
 
 export class ChannelId extends u64 {}
-export class DAOId extends u64 {}
 
 // common types between Forum and Proposal Discussions modules
 export class ThreadId extends u64 {}
@@ -112,9 +96,11 @@ export const WorkingGroupDef = {
   // _Reserved1
   Storage: Null,
   Content: Null,
-  Operations: Null,
+  OperationsAlpha: Null,
   Gateway: Null,
   Distribution: Null,
+  OperationsBeta: Null,
+  OperationsGamma: Null,
 } as const
 export type WorkingGroupKey = keyof typeof WorkingGroupDef
 export class WorkingGroup extends JoyEnum({
@@ -164,7 +150,6 @@ export const commonTypes: RegistryTypes = {
   Address,
   LookupSource,
   ChannelId,
-  DAOId,
   Url,
 }
 

+ 1 - 1
types/src/index.ts

@@ -86,7 +86,7 @@ type CreateInterface_NoOption<T extends Codec> =
       ? CreateInterface<S>[]
       : T extends BTreeMap<infer K, infer V>
       ? Map<K, V>
-      : any)
+      : unknown)
 
 // Wrapper for CreateInterface_NoOption that includes resolving an Option
 // (nested Options like Option<Option<Codec>> will resolve to Option<any>, but there are very edge case)

+ 40 - 29
types/src/scripts/generateRegistryJson.ts

@@ -5,63 +5,74 @@ import { Constructor, Codec, RegistryTypes, Registry } from '@polkadot/types/typ
 import { TypeRegistry } from '@polkadot/types'
 import fs from 'fs'
 import path from 'path'
+import _ from 'lodash'
 
 const OUTPUT_PATH = path.join(__dirname, '../../augment/all/defs.json')
 
-function normalizeDef(registry: Registry, defOrConstructor: any, typeName: string): RegistryTypes[string] {
+function normalizeDef(registry: Registry, defOrConstructor: unknown, typeName: string): RegistryTypes[string] {
   if (typeof defOrConstructor === 'string') {
+    let typeName: string = defOrConstructor
     // Replace unhandled BTreeSet with Vec
     // FIXME: Remove after updating @polkadot/api!
-    defOrConstructor = defOrConstructor.replace('BTreeSet<', 'Vec<')
+    typeName = typeName.replace('BTreeSet<', 'Vec<')
     // Workaround for "Unhandled type VecFixed"
-    defOrConstructor = defOrConstructor.replace('[u8;32]', 'Hash')
-    return defOrConstructor
-  } else if (typeof defOrConstructor === 'function') {
-    const defString = new (defOrConstructor as Constructor<Codec>)(registry).toRawType().toString()
-    let obj: any
+    typeName = typeName.replace('[u8;32]', 'Hash')
+    return typeName
+  }
+
+  if (typeof defOrConstructor === 'function') {
+    const TypeConstructor = defOrConstructor as Constructor<Codec>
+    const defString = new TypeConstructor(registry).toRawType().toString()
+    let obj: RegistryTypes[string]
 
     try {
       obj = JSON.parse(defString)
     } catch (e) {
-      // def if just a type name:
+      // def is a string (type name)
       return defString
     }
 
-    // def is an object:
-    const normalizedObj: any = {}
-    if (obj._enum && Array.isArray(obj._enum)) {
-      // Enum as array - No need to normalize
+    // String (type name) - no need to normalize
+    if (typeof obj === 'string') {
       return obj
-    } else if (obj._enum && !Array.isArray(obj._enum)) {
-      // Enum as object - normalize properties
-      normalizedObj._enum = {}
-      Object.entries(obj._enum).forEach(([key, value]) => {
+    }
+
+    // Enum as array - no need to normalize
+    if (typeof obj === 'object' && '_enum' in obj && Array.isArray(obj._enum)) {
+      return obj
+    }
+
+    // Enum as object - normalize properties
+    if (typeof obj === 'object' && '_enum' in obj && typeof obj._enum === 'object' && !Array.isArray(obj._enum)) {
+      const normalizedEnumDef = _.mapValues(obj._enum, (value, key) => {
         const normalizedValue = normalizeDef(registry, value, `${typeName}[${key}]`)
         if (typeof normalizedValue !== 'string') {
           throw new Error(
             `Too many nested definitions in ${typeName} enum. Did you forget to expose some types in the registry?`
           )
         }
-        normalizedObj._enum[key] = normalizedValue
-      })
-    } else if (obj._set) {
-      // Set - we don't need those now, but perhaps worth looking into at some point
+        return normalizedValue
+      }) as Record<string, string>
+      return { _enum: normalizedEnumDef }
+    }
+
+    // Set - not supported now
+    if ('_set' in obj) {
       throw new Error('_set definitions are not supported yet!')
-    } else {
-      // Struct - normalize properties
-      for (const [key, value] of Object.entries(obj)) {
-        // Prevent interface clashes
+    }
+
+    // Struct - normalize properties
+    if (typeof obj === 'object' && !('_enum' in obj) && !('_set' in obj)) {
+      return _.mapValues(obj, (value, key) => {
         const normalizedValue = normalizeDef(registry, value, `${typeName}[${key}]`)
         if (typeof normalizedValue !== 'string') {
           throw new Error(
             `Too many nested definitions in ${typeName} struct. Did you forget to expose some types in the registry?`
           )
         }
-        normalizedObj[key] = normalizedValue
-      }
+        return normalizedValue
+      })
     }
-
-    return normalizedObj
   }
 
   throw new Error(`Unkown type entry for ${typeName} found in registry!`)
@@ -72,7 +83,7 @@ function defsFromTypes(types: RegistryTypes) {
   registry.setKnownTypes({ types })
   registry.register(types)
   const defs: RegistryTypes = {}
-  Object.entries(registry.knownTypes.types as any).forEach(([typeName, defOrConstructor]) => {
+  Object.entries(registry.knownTypes.types as Omit<RegistryTypes, string>).forEach(([typeName, defOrConstructor]) => {
     const def = normalizeDef(registry, defOrConstructor, typeName)
     defs[typeName] = def
   })

+ 9 - 0
yarn.lock

@@ -5822,6 +5822,11 @@
   resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.0.tgz#1b0b819b1636c7baf0d6785d030d12edf70c3e83"
   integrity "sha1-GwuBmxY2x7rw1nhdAw0S7fcMPoM= sha512-iTs9HReBu7evG77Q4EC8hZnqRt57irBDkK9nvmHroiOIVwYMQc4IvYvdRgwKfYepunIY7Oh/dBuuld+Gj9uo6w=="
 
+"@types/iso-3166-2@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@types/iso-3166-2/-/iso-3166-2-1.0.0.tgz#98a7b6e505c031e83c5aac13c9c49f9d9f6ca234"
+  integrity sha512-DYDyoRyPyxBeI9bYoTXLfsOZH12m1anrWEj9LU5Sl9rgsJ4soJMYf/7byozM+64Smn6/a1i079eQLGuPykwaHQ==
+
 "@types/isomorphic-fetch@^0.0.35":
   version "0.0.35"
   resolved "https://registry.yarnpkg.com/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.35.tgz#c1c0d402daac324582b6186b91f8905340ea3361"
@@ -18886,6 +18891,10 @@ iso-639-1@^2.1.9:
   version "2.1.9"
   resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.1.9.tgz#e41b11d4f1808e5316d0252c3fa16eeb9b37bb58"
   integrity sha512-owRu9up+Cpx/hwSzm83j6G8PtC7U99UCtPVItsafefNfEgMl+pi8KBwhXwJkJfp6IouyYWFxj8n24SvCWpKZEQ==
+iso-3166-2@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/iso-3166-2/-/iso-3166-2-1.0.0.tgz#20c5cda527b56bfc7409c6802d9bff0119086131"
+  integrity sha512-xLAazfKZzwlsg/Zz/GQGQk3jJez5/2ORrjD3TjSuqz/arMht/xTK49c0GOE3afO/gEd9tHtBVVlfBla01unUng==
 
 iso-constants@^0.1.2:
   version "0.1.2"

Some files were not shown because too many files changed in this diff