Merge branch 'travis/hookshot-github' into travis/hookshot-jira

This commit is contained in:
Travis Ralston 2021-11-30 15:37:47 -07:00
commit feca813b62
31 changed files with 1731 additions and 939 deletions

View File

@ -16,8 +16,8 @@
"lint:app": "eslint src", "lint:app": "eslint src",
"lint:web": "eslint web", "lint:web": "eslint web",
"i18n": "npm run-script i18n:init && npm run-script i18n:extract", "i18n": "npm run-script i18n:init && npm run-script i18n:extract",
"i18n:init": "ngx-translate-extract --input ./web --output ./web/public/assets/i18n/template.json --key-as-default-value --replace --format json", "i18n:init": "ngx-translate-extract --input ./web --output ./web/assets/i18n/template.json --key-as-default-value --replace --format json",
"i18n:extract": "ngx-translate-extract --input ./web --output ./web/public/assets/i18n/en.json --clean --format json" "i18n:extract": "ngx-translate-extract --input ./web --output ./web/assets/i18n/en.json --key-as-default-value --clean --format json"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -51,6 +51,7 @@ export const CACHE_FEDERATION = "federation";
export const CACHE_IRC_BRIDGE = "irc-bridge"; export const CACHE_IRC_BRIDGE = "irc-bridge";
export const CACHE_STICKERS = "stickers"; export const CACHE_STICKERS = "stickers";
export const CACHE_TELEGRAM_BRIDGE = "telegram-bridge"; export const CACHE_TELEGRAM_BRIDGE = "telegram-bridge";
export const CACHE_HOOKSHOT_GITHUB_BRIDGE = "hookshot-github-bridge";
export const CACHE_WEBHOOKS_BRIDGE = "webhooks-bridge"; export const CACHE_WEBHOOKS_BRIDGE = "webhooks-bridge";
export const CACHE_SIMPLE_BOTS = "simple-bots"; export const CACHE_SIMPLE_BOTS = "simple-bots";
export const CACHE_SLACK_BRIDGE = "slack-bridge"; export const CACHE_SLACK_BRIDGE = "slack-bridge";

View File

@ -0,0 +1,110 @@
import { Context, GET, Path, PathParam, POST, QueryParam, Security, ServiceContext } from "typescript-rest";
import { Cache, CACHE_HOOKSHOT_GITHUB_BRIDGE, CACHE_INTEGRATIONS, CACHE_TELEGRAM_BRIDGE } from "../../MemoryCache";
import { LogService } from "matrix-bot-sdk";
import { ApiError } from "../ApiError";
import { ROLE_ADMIN, ROLE_USER } from "../security/MatrixSecurity";
import HookshotGithubBridgeRecord from "../../db/models/HookshotGithubBridgeRecord";
interface CreateWithUpstream {
upstreamId: number;
}
interface CreateSelfhosted {
provisionUrl: string;
sharedSecret: string;
}
interface BridgeResponse {
id: number;
upstreamId?: number;
provisionUrl?: string;
sharedSecret?: string;
isEnabled: boolean;
}
/**
* Administrative API for configuring Hookshot Github bridge instances.
*/
@Path("/api/v1/dimension/admin/hookshot/github")
export class AdminTelegramService {
@Context
private context: ServiceContext;
@GET
@Path("all")
@Security([ROLE_USER, ROLE_ADMIN])
public async getBridges(): Promise<BridgeResponse[]> {
const bridges = await HookshotGithubBridgeRecord.findAll();
return Promise.all(bridges.map(async b => {
return {
id: b.id,
upstreamId: b.upstreamId,
provisionUrl: b.provisionUrl,
sharedSecret: b.sharedSecret,
isEnabled: b.isEnabled,
};
}));
}
@GET
@Path(":bridgeId")
@Security([ROLE_USER, ROLE_ADMIN])
public async getBridge(@PathParam("bridgeId") bridgeId: number): Promise<BridgeResponse> {
const telegramBridge = await HookshotGithubBridgeRecord.findByPk(bridgeId);
if (!telegramBridge) throw new ApiError(404, "Github Bridge not found");
return {
id: telegramBridge.id,
upstreamId: telegramBridge.upstreamId,
provisionUrl: telegramBridge.provisionUrl,
sharedSecret: telegramBridge.sharedSecret,
isEnabled: telegramBridge.isEnabled,
};
}
@POST
@Path(":bridgeId")
@Security([ROLE_USER, ROLE_ADMIN])
public async updateBridge(@PathParam("bridgeId") bridgeId: number, request: CreateSelfhosted): Promise<BridgeResponse> {
const userId = this.context.request.user.userId;
const bridge = await HookshotGithubBridgeRecord.findByPk(bridgeId);
if (!bridge) throw new ApiError(404, "Bridge not found");
bridge.provisionUrl = request.provisionUrl;
bridge.sharedSecret = request.sharedSecret;
await bridge.save();
LogService.info("AdminHookshotGithubService", userId + " updated Hookshot Github Bridge " + bridge.id);
Cache.for(CACHE_HOOKSHOT_GITHUB_BRIDGE).clear();
Cache.for(CACHE_INTEGRATIONS).clear();
return this.getBridge(bridge.id);
}
@POST
@Path("new/upstream")
@Security([ROLE_USER, ROLE_ADMIN])
public async newConfigForUpstream(@QueryParam("scalar_token") _scalarToken: string, _request: CreateWithUpstream): Promise<BridgeResponse> {
throw new ApiError(400, "Cannot create a github bridge from an upstream");
}
@POST
@Path("new/selfhosted")
@Security([ROLE_USER, ROLE_ADMIN])
public async newSelfhosted(request: CreateSelfhosted): Promise<BridgeResponse> {
const userId = this.context.request.user.userId;
const bridge = await HookshotGithubBridgeRecord.create({
provisionUrl: request.provisionUrl,
sharedSecret: request.sharedSecret,
isEnabled: true,
});
LogService.info("AdminTelegramService", userId + " created a new Hookshot Github Bridge with provisioning URL " + request.provisionUrl);
Cache.for(CACHE_HOOKSHOT_GITHUB_BRIDGE).clear();
Cache.for(CACHE_INTEGRATIONS).clear();
return this.getBridge(bridge.id);
}
}

View File

@ -0,0 +1,101 @@
import { LogService } from "matrix-bot-sdk";
import * as request from "request";
import HookshotGithubBridgeRecord from "../db/models/HookshotGithubBridgeRecord";
import {
HookshotConnection,
HookshotConnectionsResponse,
HookshotGithubRoomConfig,
HookshotTypes
} from "./models/hookshot";
export class HookshotGithubBridge {
constructor(private requestingUserId: string) {
}
private async getDefaultBridge(): Promise<HookshotGithubBridgeRecord> {
const bridges = await HookshotGithubBridgeRecord.findAll({where: {isEnabled: true}});
if (!bridges || bridges.length !== 1) {
throw new Error("No bridges or too many bridges found");
}
return bridges[0];
}
public async isBridgingEnabled(): Promise<boolean> {
const bridges = await HookshotGithubBridgeRecord.findAll({where: {isEnabled: true}});
return !!bridges && bridges.length > 0;
}
public async getRoomConfigurations(inRoomId: string): Promise<HookshotGithubRoomConfig[]> {
const bridge = await this.getDefaultBridge();
try {
const connections = await this.doProvisionRequest<HookshotConnectionsResponse>(bridge, "GET", `/v1/${inRoomId}/connections`);
return connections.filter(c => c.type === HookshotTypes.Github);
} catch (e) {
if (e.errBody['error'] === "Could not determine if the user is in the room.") {
return [];
}
throw e;
}
}
public async bridgeRoom(roomId: string): Promise<HookshotGithubRoomConfig> {
const bridge = await this.getDefaultBridge();
const body = {};
return await this.doProvisionRequest<HookshotConnection>(bridge, "PUT", `/v1/${roomId}/connections/${HookshotTypes.Github}`, null, body);
}
public async unbridgeRoom(roomId: string, connectionId: string): Promise<void> {
const bridge = await this.getDefaultBridge();
await this.doProvisionRequest(bridge, "DELETE", `/v1/${roomId}/connections/${connectionId}`);
}
private async doProvisionRequest<T>(bridge: HookshotGithubBridgeRecord, method: string, endpoint: string, qs?: any, body?: any): Promise<T> {
const provisionUrl = bridge.provisionUrl;
const apiUrl = provisionUrl.endsWith("/") ? provisionUrl.substring(0, provisionUrl.length - 1) : provisionUrl;
const url = apiUrl + (endpoint.startsWith("/") ? endpoint : "/" + endpoint);
LogService.info("TelegramBridge", "Doing provision Github Hookshot Bridge request: " + url);
if (!qs) qs = {};
if (qs["userId"] === false) delete qs["userId"];
else if (!qs["userId"]) qs["userId"] = this.requestingUserId;
return new Promise<T>((resolve, reject) => {
request({
method: method,
url: url,
qs: qs,
json: body,
headers: {
"Authorization": `Bearer ${bridge.sharedSecret}`,
},
}, (err, res, _body) => {
try {
if (err) {
LogService.error("GithubHookshotBridge", "Error calling" + url);
LogService.error("GithubHookshotBridge", err);
reject(err);
} else if (!res) {
LogService.error("GithubHookshotBridge", "There is no response for " + url);
reject(new Error("No response provided - is the service online?"));
} else if (res.statusCode !== 200 && res.statusCode !== 202) {
LogService.error("GithubHookshotBridge", "Got status code " + res.statusCode + " when calling " + url);
LogService.error("GithubHookshotBridge", res.body);
if (typeof (res.body) === "string") res.body = JSON.parse(res.body);
reject({errBody: res.body, error: new Error("Request failed")});
} else {
if (typeof (res.body) === "string") res.body = JSON.parse(res.body);
resolve(res.body);
}
} catch (e) {
LogService.error("GithubHookshotBridge", e);
reject(e);
}
});
});
}
}

View File

@ -0,0 +1,16 @@
export interface HookshotConnection {
type: string;
id: string;
service: string; // human-readable
details: any; // context-specific
}
export type HookshotConnectionsResponse = HookshotConnection[];
export interface HookshotGithubRoomConfig {
}
export enum HookshotTypes {
Github = "uk.half-shot.matrix-hookshot.github.repository",
}

View File

@ -1,5 +1,5 @@
import { import {
Bridge, Bridge, HookshotGithubBridgeConfiguration,
SlackBridgeConfiguration, SlackBridgeConfiguration,
TelegramBridgeConfiguration, TelegramBridgeConfiguration,
WebhookBridgeConfiguration WebhookBridgeConfiguration
@ -10,6 +10,7 @@ import { LogService } from "matrix-bot-sdk";
import { TelegramBridge } from "../bridges/TelegramBridge"; import { TelegramBridge } from "../bridges/TelegramBridge";
import { WebhooksBridge } from "../bridges/WebhooksBridge"; import { WebhooksBridge } from "../bridges/WebhooksBridge";
import { SlackBridge } from "../bridges/SlackBridge"; import { SlackBridge } from "../bridges/SlackBridge";
import { HookshotGithubBridge } from "../bridges/HookshotGithubBridge";
export class BridgeStore { export class BridgeStore {
@ -59,7 +60,7 @@ export class BridgeStore {
const record = await BridgeRecord.findOne({where: {type: integrationType}}); const record = await BridgeRecord.findOne({where: {type: integrationType}});
if (!record) throw new Error("Bridge not found"); if (!record) throw new Error("Bridge not found");
const hasDedicatedApi = ["irc", "telegram", "webhooks", "slack"]; const hasDedicatedApi = ["irc", "telegram", "webhooks", "slack", "hookshot_github"];
if (hasDedicatedApi.indexOf(integrationType) !== -1) { if (hasDedicatedApi.indexOf(integrationType) !== -1) {
throw new Error("This bridge should be modified with the dedicated API"); throw new Error("This bridge should be modified with the dedicated API");
} else throw new Error("Unsupported bridge"); } else throw new Error("Unsupported bridge");
@ -78,6 +79,9 @@ export class BridgeStore {
} else if (record.type === "slack") { } else if (record.type === "slack") {
const slack = new SlackBridge(requestingUserId); const slack = new SlackBridge(requestingUserId);
return slack.isBridgingEnabled(); return slack.isBridgingEnabled();
} else if (record.type === "hookshot_github") {
const hookshot = new HookshotGithubBridge(requestingUserId);
return hookshot.isBridgingEnabled();
} else return true; } else return true;
} }
@ -94,6 +98,9 @@ export class BridgeStore {
} else if (record.type === "slack") { } else if (record.type === "slack") {
const slack = new SlackBridge(requestingUserId); const slack = new SlackBridge(requestingUserId);
return slack.isBridgingEnabled(); return slack.isBridgingEnabled();
} else if (record.type === "hookshot_github") {
const hookshot = new HookshotGithubBridge(requestingUserId);
return hookshot.isBridgingEnabled();
} else return false; } else return false;
} }
@ -131,6 +138,14 @@ export class BridgeStore {
link: link, link: link,
botUserId: info.botUserId, botUserId: info.botUserId,
}; };
} else if (record.type === "hookshot_github") {
if (!inRoomId) return {}; // The bridge's admin config is handled by other APIs
const hookshot = new HookshotGithubBridge(requestingUserId);
const connections = await hookshot.getRoomConfigurations(inRoomId);
return <HookshotGithubBridgeConfiguration>{
botUserId: "@hookshot_bot:localhost", // TODO
connections: connections,
};
} else return {}; } else return {};
} }

View File

@ -29,6 +29,7 @@ import TermsRecord from "./models/TermsRecord";
import TermsTextRecord from "./models/TermsTextRecord"; import TermsTextRecord from "./models/TermsTextRecord";
import TermsSignedRecord from "./models/TermsSignedRecord"; import TermsSignedRecord from "./models/TermsSignedRecord";
import TermsUpstreamRecord from "./models/TermsUpstreamRecord"; import TermsUpstreamRecord from "./models/TermsUpstreamRecord";
import HookshotGithubBridgeRecord from "./models/HookshotGithubBridgeRecord";
class _DimensionStore { class _DimensionStore {
private sequelize: Sequelize; private sequelize: Sequelize;
@ -75,6 +76,7 @@ class _DimensionStore {
TermsTextRecord, TermsTextRecord,
TermsSignedRecord, TermsSignedRecord,
TermsUpstreamRecord, TermsUpstreamRecord,
HookshotGithubBridgeRecord,
]); ]);
} }

View File

@ -13,7 +13,7 @@ export default {
{ {
type: "gitter", type: "gitter",
name: "Gitter Bridge", name: "Gitter Bridge",
avatarUrl: "/img/avatars/gitter.png", avatarUrl: "/assets/img/avatars/gitter.png",
isEnabled: true, isEnabled: true,
isPublic: true, isPublic: true,
description: "Bridges Gitter rooms to Matrix", description: "Bridges Gitter rooms to Matrix",

View File

@ -0,0 +1,23 @@
import { QueryInterface } from "sequelize";
import { DataType } from "sequelize-typescript";
export default {
up: (queryInterface: QueryInterface) => {
return Promise.resolve()
.then(() => queryInterface.createTable("dimension_hookshot_github_bridges", {
"id": {type: DataType.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false},
"upstreamId": {
type: DataType.INTEGER, allowNull: true,
references: {model: "dimension_upstreams", key: "id"},
onUpdate: "cascade", onDelete: "cascade",
},
"provisionUrl": {type: DataType.STRING, allowNull: true},
"sharedSecret": {type: DataType.STRING, allowNull: true},
"isEnabled": {type: DataType.BOOLEAN, allowNull: false},
}));
},
down: (queryInterface: QueryInterface) => {
return Promise.resolve()
.then(() => queryInterface.dropTable("dimension_hookshot_github_bridges"));
}
}

View File

@ -0,0 +1,23 @@
import { QueryInterface } from "sequelize";
export default {
up: (queryInterface: QueryInterface) => {
return Promise.resolve()
.then(() => queryInterface.bulkInsert("dimension_bridges", [
{
type: "hookshot_github",
name: "Github Bridge",
avatarUrl: "/assets/img/avatars/github.png",
isEnabled: true,
isPublic: true,
description: "Bridges Github issues to Matrix",
},
]));
},
down: (queryInterface: QueryInterface) => {
return Promise.resolve()
.then(() => queryInterface.bulkDelete("dimension_bridges", {
type: "hookshot_github",
}));
}
}

View File

@ -0,0 +1,30 @@
import { AllowNull, AutoIncrement, Column, ForeignKey, Model, PrimaryKey, Table } from "sequelize-typescript";
import Upstream from "./Upstream";
@Table({
tableName: "dimension_hookshot_github_bridges",
underscored: false,
timestamps: false,
})
export default class HookshotGithubBridgeRecord extends Model {
@PrimaryKey
@AutoIncrement
@Column
id: number;
@AllowNull
@Column
@ForeignKey(() => Upstream)
upstreamId?: number;
@AllowNull
@Column
provisionUrl?: string;
@AllowNull
@Column
sharedSecret?: string;
@Column
isEnabled: boolean;
}

View File

@ -1,4 +1,4 @@
import { LogLevel, LogService } from "matrix-bot-sdk"; import { LogLevel, LogService, RichConsoleLogger } from "matrix-bot-sdk";
import { DimensionStore } from "./db/DimensionStore"; import { DimensionStore } from "./db/DimensionStore";
import Webserver from "./api/Webserver"; import Webserver from "./api/Webserver";
import { CURRENT_VERSION } from "./version"; import { CURRENT_VERSION } from "./version";
@ -16,6 +16,7 @@ declare global {
} }
LogService.setLevel(LogLevel.DEBUG); LogService.setLevel(LogLevel.DEBUG);
LogService.setLogger(new RichConsoleLogger());
LogService.info("index", "Starting dimension " + CURRENT_VERSION); LogService.info("index", "Starting dimension " + CURRENT_VERSION);
async function startup() { async function startup() {

View File

@ -4,6 +4,7 @@ import { AvailableNetworks, LinkedChannels } from "../bridges/IrcBridge";
import { PortalInfo, PuppetInfo } from "../bridges/TelegramBridge"; import { PortalInfo, PuppetInfo } from "../bridges/TelegramBridge";
import { WebhookConfiguration } from "../bridges/models/webhooks"; import { WebhookConfiguration } from "../bridges/models/webhooks";
import { BridgedChannel } from "../bridges/SlackBridge"; import { BridgedChannel } from "../bridges/SlackBridge";
import { HookshotConnection } from "../bridges/models/hookshot";
const PRIVATE_ACCESS_SUPPORTED_BRIDGES = ["webhooks"]; const PRIVATE_ACCESS_SUPPORTED_BRIDGES = ["webhooks"];
@ -45,3 +46,8 @@ export interface SlackBridgeConfiguration {
link: BridgedChannel; link: BridgedChannel;
botUserId: string; botUserId: string;
} }
export interface HookshotGithubBridgeConfiguration {
botUserId: string;
connections: HookshotConnection[];
}

View File

@ -0,0 +1,41 @@
<div *ngIf="isLoading">
<my-spinner></my-spinner>
</div>
<div *ngIf="!isLoading">
<my-ibox boxTitle="Github Bridge Configurations">
<div class="my-ibox-content">
<p>
<a href="https://github.com/half-shot/matrix-hookshot" target="_blank">{{'matrix-hookshot' | translate}}</a>
{{'is a multi-purpose bridge which supports Github as an integration. If enabled in the configuration, it can be used here to offer a UI for setting up a room to pipe to a repository.' | translate}}
<table class="table table-striped table-condensed table-bordered">
<thead>
<tr>
<th>{{'Name' | translate}}</th>
<th class="text-center" style="width: 120px;">{{'Actions' | translate}}</th>
</tr>
</thead>
<tbody>
<tr *ngIf="!configurations || configurations.length === 0">
<td colspan="3"><i>{{'No bridge configurations.' | translate}}</i></td>
</tr>
<tr *ngFor="let bridge of configurations trackById">
<td>
{{ bridge.upstreamId ? "matrix.org's bridge" : "Self-hosted bridge" }}
<span class="text-muted" style="display: inline-block;"
*ngIf="!bridge.upstreamId">({{ bridge.provisionUrl }})</span>
</td>
<td class="text-center">
<span class="editButton" (click)="editBridge(bridge)">
<i class="fa fa-pencil-alt"></i>
</span>
</td>
</tr>
</tbody>
</table>
<button type="button" class="btn btn-success btn-sm" (click)="addSelfHostedBridge()"
[disabled]="configurations && configurations.length > 0">
<i class="fa fa-plus"></i> {{'Add self-hosted bridge' | translate}}
</button>
</div>
</my-ibox>
</div>

View File

@ -0,0 +1,3 @@
.editButton {
cursor: pointer;
}

View File

@ -0,0 +1,86 @@
import { Component, OnInit } from "@angular/core";
import { ToasterService } from "angular2-toaster";
import {
AdminHookshotGithubBridgeManageSelfhostedComponent,
ManageSelfhostedHookshotGithubBridgeDialogContext
} from "./manage-selfhosted/manage-selfhosted.component";
import { FE_TelegramBridge } from "../../../shared/models/telegram";
import { TranslateService } from "@ngx-translate/core";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
import { AdminHookshotGithubApiService } from "../../../shared/services/admin/admin-hookshot-github-api.service";
import { FE_HookshotGithubBridge } from "../../../shared/models/hookshot_github";
@Component({
templateUrl: "./hookshot-github.component.html",
styleUrls: ["./hookshot-github.component.scss"],
})
export class AdminHookshotGithubBridgeComponent implements OnInit {
public isLoading = true;
public isUpdating = false;
public configurations: FE_TelegramBridge[] = [];
constructor(private hookshotApi: AdminHookshotGithubApiService,
private toaster: ToasterService,
private modal: NgbModal,
public translate: TranslateService) {
this.translate = translate;
}
public ngOnInit() {
this.reload().then(() => this.isLoading = false);
}
private async reload(): Promise<any> {
try {
this.configurations = await this.hookshotApi.getBridges();
} catch (err) {
console.error(err);
this.translate.get('Error loading bridges').subscribe((res: string) => {
this.toaster.pop("error", res);
});
}
}
public addSelfHostedBridge() {
const selfhostedRef = this.modal.open(AdminHookshotGithubBridgeManageSelfhostedComponent, {
backdrop: 'static',
size: 'lg',
});
selfhostedRef.result.then(() => {
try {
this.reload()
} catch (err) {
console.error(err);
this.translate.get('Failed to get an updated Github bridge list').subscribe((res: string) => {
this.toaster.pop("error", res);
});
}
})
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedHookshotGithubBridgeDialogContext;
selfhostedInstance.provisionUrl = '';
selfhostedInstance.sharedSecret = '';
}
public editBridge(bridge: FE_HookshotGithubBridge) {
const selfhostedRef = this.modal.open(AdminHookshotGithubBridgeManageSelfhostedComponent, {
backdrop: 'static',
size: 'lg',
});
selfhostedRef.result.then(() => {
try {
this.reload()
} catch (err) {
console.error(err);
this.translate.get('Failed to get an updated Github bridge list').subscribe((res: string) => {
this.toaster.pop("error", res);
});
}
})
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedHookshotGithubBridgeDialogContext;
selfhostedInstance.provisionUrl = bridge.provisionUrl;
selfhostedInstance.sharedSecret = bridge.sharedSecret;
selfhostedInstance.bridgeId = bridge.id;
selfhostedInstance.isAdding = !bridge.id;
}
}

View File

@ -0,0 +1,31 @@
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">{{'self-hosted Github bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
</div>
<div class="modal-body">
<p>{{'Self-hosted Github bridges must have' | translate}} <code>{{'provisioning' | translate}}</code> {{'enabled in the configuration.' | translate}}</p>
<label class="label-block">
{{'Provisioning URL' | translate}}
<span class="text-muted ">{{'The provisioning URL for the bridge. This is the specific address for the bridge given in the configuration.' | translate}}</span>
<input type="text" class="form-control"
placeholder="http://localhost:9999/_matrix/provision/v1"
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
</label>
<label class="label-block">
{{'Shared Secret' | translate}}
<span class="text-muted ">{{'The shared secret defined in the configuration for provisioning.' | translate}}</span>
<input type="text" class="form-control"
placeholder="some_secret_value"
[(ngModel)]="sharedSecret" [disabled]="isSaving"/>
</label>
</div>
<div class="modal-footer">
<button type="button" (click)="add()" title="save" class="btn btn-primary btn-sm">
<i class="far fa-save"></i> {{'Save' | translate}}
</button>
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
</button>
</div>

View File

@ -0,0 +1,64 @@
import { Component } from "@angular/core";
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
import { ToasterService } from "angular2-toaster";
import { AdminTelegramApiService } from "../../../../shared/services/admin/admin-telegram-api.service";
import { TranslateService } from "@ngx-translate/core";
import { AdminHookshotGithubApiService } from "../../../../shared/services/admin/admin-hookshot-github-api.service";
export interface ManageSelfhostedHookshotGithubBridgeDialogContext {
provisionUrl: string;
sharedSecret: string;
bridgeId: number;
isAdding: boolean;
}
@Component({
templateUrl: "./manage-selfhosted.component.html",
styleUrls: ["./manage-selfhosted.component.scss"],
})
export class AdminHookshotGithubBridgeManageSelfhostedComponent {
isSaving = false;
provisionUrl: string;
sharedSecret: string;
bridgeId: number;
isAdding = true;
constructor(public modal: NgbActiveModal,
private hookshotApi: AdminHookshotGithubApiService,
private toaster: ToasterService,
public translate: TranslateService) {
this.translate = translate;
}
public add() {
this.isSaving = true;
if (this.isAdding) {
this.hookshotApi.newSelfhosted(this.provisionUrl, this.sharedSecret).then(() => {
this.translate.get('Github bridge added').subscribe((res: string) => {
this.toaster.pop("success", res);
});
this.modal.close();
}).catch(err => {
console.error(err);
this.isSaving = false;
this.translate.get('Failed to create Github bridge').subscribe((res: string) => {
this.toaster.pop("error", res);
});
});
} else {
this.hookshotApi.updateSelfhosted(this.bridgeId, this.provisionUrl, this.sharedSecret).then(() => {
this.translate.get('Github bridge updated').subscribe((res: string) => {
this.toaster.pop("success", res);
});
this.modal.close();
}).catch(err => {
console.error(err);
this.isSaving = false;
this.translate.get('Failed to update Github bridge').subscribe((res: string) => {
this.toaster.pop("error", res);
});
});
}
}
}

View File

@ -119,6 +119,11 @@ import { AdminWidgetWhiteboardConfigComponent } from "./admin/widgets/whiteboard
import { TranslateLoader, TranslateModule } from "@ngx-translate/core"; import { TranslateLoader, TranslateModule } from "@ngx-translate/core";
import { TranslateHttpLoader } from "@ngx-translate/http-loader"; import { TranslateHttpLoader } from "@ngx-translate/http-loader";
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { AdminHookshotGithubBridgeComponent } from "./admin/bridges/hookshot-github/hookshot-github.component";
import { AdminHookshotGithubBridgeManageSelfhostedComponent } from "./admin/bridges/hookshot-github/manage-selfhosted/manage-selfhosted.component";
import { AdminHookshotGithubApiService } from "./shared/services/admin/admin-hookshot-github-api.service";
import { HookshotGithubApiService } from "./shared/services/integrations/hookshot-github-api.service";
import { HookshotGithubBridgeConfigComponent } from "./configs/bridge/hookshot-github/hookshot-github.bridge.component";
// AoT requires an exported function for factories // AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) { export function HttpLoaderFactory(http: HttpClient) {
@ -227,7 +232,10 @@ export function HttpLoaderFactory(http: HttpClient) {
AdminTermsNewEditPublishDialogComponent, AdminTermsNewEditPublishDialogComponent,
TermsWidgetWrapperComponent, TermsWidgetWrapperComponent,
WhiteboardWidgetComponent, WhiteboardWidgetComponent,
AdminWidgetWhiteboardConfigComponent AdminWidgetWhiteboardConfigComponent,
AdminHookshotGithubBridgeComponent,
AdminHookshotGithubBridgeManageSelfhostedComponent,
HookshotGithubBridgeConfigComponent,
// Vendor // Vendor
], ],
@ -257,6 +265,8 @@ export function HttpLoaderFactory(http: HttpClient) {
AdminSlackApiService, AdminSlackApiService,
ToasterService, ToasterService,
AdminTermsApiService, AdminTermsApiService,
AdminHookshotGithubApiService,
HookshotGithubApiService,
{provide: Window, useValue: window}, {provide: Window, useValue: window},
// Vendor // Vendor

View File

@ -48,6 +48,8 @@ import { AdminTermsComponent } from "./admin/terms/terms.component";
import { AdminNewEditTermsComponent } from "./admin/terms/new-edit/new-edit.component"; import { AdminNewEditTermsComponent } from "./admin/terms/new-edit/new-edit.component";
import { TermsWidgetWrapperComponent } from "./widget-wrappers/terms/terms.component"; import { TermsWidgetWrapperComponent } from "./widget-wrappers/terms/terms.component";
import { WhiteboardWidgetComponent } from "./configs/widget/whiteboard/whiteboard.widget.component"; import { WhiteboardWidgetComponent } from "./configs/widget/whiteboard/whiteboard.widget.component";
import { AdminHookshotGithubBridgeComponent } from "./admin/bridges/hookshot-github/hookshot-github.component";
import { HookshotGithubBridgeConfigComponent } from "./configs/bridge/hookshot-github/hookshot-github.bridge.component";
const routes: Routes = [ const routes: Routes = [
{path: "", component: HomeComponent}, {path: "", component: HomeComponent},
@ -134,6 +136,11 @@ const routes: Routes = [
component: AdminSlackBridgeComponent, component: AdminSlackBridgeComponent,
data: {breadcrumb: "Slack Bridge", name: "Slack Bridge"}, data: {breadcrumb: "Slack Bridge", name: "Slack Bridge"},
}, },
{
path: "hookshot_github",
component: AdminHookshotGithubBridgeComponent,
data: {breadcrumb: "Github Bridge", name: "Github Bridge"},
},
], ],
}, },
{ {
@ -272,6 +279,11 @@ const routes: Routes = [
component: SlackBridgeConfigComponent, component: SlackBridgeConfigComponent,
data: {breadcrumb: "Slack Bridge Configuration", name: "Slack Bridge Configuration"}, data: {breadcrumb: "Slack Bridge Configuration", name: "Slack Bridge Configuration"},
}, },
{
path: "hookshot_github",
component: HookshotGithubBridgeConfigComponent,
data: {breadcrumb: "Github Bridge Configuration", name: "Github Bridge Configuration"},
},
], ],
}, },
{ {

View File

@ -0,0 +1,44 @@
<my-bridge-config [bridgeComponent]="this">
<ng-template #bridgeParamsTemplate>
<my-ibox [isCollapsible]="false">
<h5 class="my-ibox-title">
{{'Bridge to Github' | translate}}
</h5>
<div class="my-ibox-content" *ngIf="loadingConnections">
<my-spinner></my-spinner>
</div>
<div class="my-ibox-content" *ngIf="!loadingConnections">
<div *ngIf="!isBridged && needsAuth">
<p>
{{'In order to bridge to Github, you\'ll need to authorize the bridge to access your organization(s). Please click the button below to do so.' | translate}}
</p>
<a [href]="authUrl" rel="noopener" target="_blank">
<img src="/assets/img/slack_auth_button.png" alt="sign in with slack"/>
</a>
</div>
<div *ngIf="!isBridged && !needsAuth">
<label class="label-block">
{{'Organization' | translate}}
<select class="form-control form-control-sm" [(ngModel)]="orgId"
(change)="loadRepos()" [disabled]="isBusy">
<option *ngFor="let org of orgs" [ngValue]="org">
{{ org }}
</option>
</select>
</label>
<label class="label-block">
{{'Repository' | translate}}
<select class="form-control form-control-sm" [(ngModel)]="repoId" [disabled]="isBusy">
<option *ngFor="let repo of repos" [ngValue]="repo">
{{ repo }}
</option>
</select>
</label>
<button type="button" class="btn btn-sm btn-primary" [disabled]="isBusy" (click)="bridgeRoom()">
Bridge
</button>
</div>
</div>
</my-ibox>
</ng-template>
</my-bridge-config>

View File

@ -0,0 +1,4 @@
.actions-col {
width: 120px;
text-align: center;
}

View File

@ -0,0 +1,101 @@
import { Component, OnInit } from "@angular/core";
import { BridgeComponent } from "../bridge.component";
import { FE_SlackChannel, FE_SlackLink, FE_SlackTeam } from "../../../shared/models/slack";
import { SlackApiService } from "../../../shared/services/integrations/slack-api.service";
import { ScalarClientApiService } from "../../../shared/services/scalar/scalar-client-api.service";
import { DomSanitizer, SafeUrl } from "@angular/platform-browser";
import { TranslateService } from "@ngx-translate/core";
import { FE_HookshotGithubBridge, FE_HookshotGithubConnection } from "../../../shared/models/hookshot_github";
import { HookshotGithubApiService } from "../../../shared/services/integrations/hookshot-github-api.service";
interface HookshotConfig {
botUserId: string;
connections: FE_HookshotGithubConnection[];
}
@Component({
templateUrl: "hookshot-github.bridge.component.html",
styleUrls: ["hookshot-github.bridge.component.scss"],
})
export class HookshotGithubBridgeConfigComponent extends BridgeComponent<HookshotConfig> implements OnInit {
public isBusy: boolean;
public needsAuth = false;
public authUrl: SafeUrl;
public loadingConnections = false;
public orgs: string[] = [];
public repos: string[] = []; // for org
public orgId: string;
public repoId: string;
constructor(private hookshot: HookshotGithubApiService, private scalar: ScalarClientApiService, public translate: TranslateService) {
super("hookshot_github", translate);
this.translate = translate;
}
public ngOnInit() {
super.ngOnInit();
this.prepare();
}
private prepare() {
}
public loadRepos() {
// TODO
}
public get isBridged(): boolean {
return this.bridge.config.connections.length > 0;
}
public async bridgeRoom(): Promise<any> {
this.isBusy = true;
try {
await this.scalar.inviteUser(this.roomId, this.bridge.config.botUserId);
} catch (e) {
if (!e.response || !e.response.error || !e.response.error._error ||
e.response.error._error.message.indexOf("already in the room") === -1) {
this.isBusy = false;
this.translate.get('Error inviting bridge').subscribe((res: string) => {
this.toaster.pop("error", res);
});
return;
}
}
this.hookshot.bridgeRoom(this.roomId).then(conn => {
this.bridge.config.connections.push(conn);
this.isBusy = false;
this.translate.get('Bridge requested').subscribe((res: string) => {
this.toaster.pop("success", res);
});
}).catch(error => {
this.isBusy = false;
console.error(error);
this.translate.get('Error requesting bridge').subscribe((res: string) => {
this.toaster.pop("error", res);
});
});
}
public unbridgeRoom(): void {
this.isBusy = true;
this.hookshot.unbridgeRoom(this.roomId).then(() => {
this.bridge.config.connections = [];
this.isBusy = false;
this.translate.get('Bridge removed').subscribe((res: string) => {
this.toaster.pop("success", res);
});
}).catch(error => {
this.isBusy = false;
console.error(error);
this.translate.get('Error removing bridge').subscribe((res: string) => {
this.toaster.pop("error", res);
});
});
}
}

View File

@ -161,6 +161,10 @@
<img src="/assets/img/avatars/slack.png"> <img src="/assets/img/avatars/slack.png">
<span>Slack</span> <span>Slack</span>
</div> </div>
<div class="integration">
<img src="/assets/img/avatars/github.png">
<span>GitHub</span>
</div>
<div class="integration"> <div class="integration">
<img src="/assets/img/avatars/webhooks.png"> <img src="/assets/img/avatars/webhooks.png">
<span>Webhooks</span> <span>Webhooks</span>

View File

@ -0,0 +1,11 @@
export interface FE_HookshotGithubBridge {
id: number;
upstreamId?: number;
provisionUrl?: string;
sharedSecret?: string;
isEnabled: boolean;
}
export interface FE_HookshotGithubConnection {
}

View File

@ -31,6 +31,7 @@ export class IntegrationsRegistry {
"telegram": {}, "telegram": {},
"webhooks": {}, "webhooks": {},
"slack": {}, "slack": {},
"hookshot_github": {},
}, },
"widget": { "widget": {
"custom": { "custom": {

View File

@ -0,0 +1,39 @@
import { Injectable } from "@angular/core";
import { AuthedApi } from "../authed-api";
import { FE_Upstream } from "../../models/admin-responses";
import { FE_TelegramBridge, FE_TelegramBridgeOptions } from "../../models/telegram";
import { HttpClient } from "@angular/common/http";
import { FE_HookshotGithubBridge } from "../../models/hookshot_github";
@Injectable()
export class AdminHookshotGithubApiService extends AuthedApi {
constructor(http: HttpClient) {
super(http);
}
public getBridges(): Promise<FE_HookshotGithubBridge[]> {
return this.authedGet<FE_HookshotGithubBridge[]>("/api/v1/dimension/admin/hookshot/github/all").toPromise();
}
public getBridge(bridgeId: number): Promise<FE_HookshotGithubBridge> {
return this.authedGet<FE_HookshotGithubBridge>("/api/v1/dimension/admin/hookshot/github/" + bridgeId).toPromise();
}
public newFromUpstream(upstream: FE_Upstream): Promise<FE_HookshotGithubBridge> {
return this.authedPost<FE_HookshotGithubBridge>("/api/v1/dimension/admin/hookshot/github/new/upstream", {upstreamId: upstream.id}).toPromise();
}
public newSelfhosted(provisionUrl: string, sharedSecret: string): Promise<FE_HookshotGithubBridge> {
return this.authedPost<FE_HookshotGithubBridge>("/api/v1/dimension/admin/hookshot/github/new/selfhosted", {
provisionUrl: provisionUrl,
sharedSecret: sharedSecret,
}).toPromise();
}
public updateSelfhosted(bridgeId: number, provisionUrl: string, sharedSecret: string): Promise<FE_HookshotGithubBridge> {
return this.authedPost<FE_TelegramBridge>("/api/v1/dimension/admin/hookshot/github/" + bridgeId, {
provisionUrl: provisionUrl,
sharedSecret: sharedSecret,
}).toPromise();
}
}

View File

@ -0,0 +1,21 @@
import { Injectable } from "@angular/core";
import { AuthedApi } from "../authed-api";
import { HttpClient } from "@angular/common/http";
import { FE_HookshotGithubConnection } from "../../models/hookshot_github";
@Injectable()
export class HookshotGithubApiService extends AuthedApi {
constructor(http: HttpClient) {
super(http);
}
public bridgeRoom(roomId: string): Promise<FE_HookshotGithubConnection> {
return this.authedPost<FE_HookshotGithubConnection>("/api/v1/dimension/hookshot/github/room/" + roomId + "/connect", {
// TODO
}).toPromise();
}
public unbridgeRoom(roomId: string): Promise<any> {
return this.authedDelete("/api/v1/dimension/hookshot/github/room/" + roomId + "/connections/all").toPromise();
}
}

View File

@ -1,467 +1,463 @@
{ {
"Dashboard": "Dashboard", "Dashboard": "Dashboard",
"Widgets": "Widgets", "Widgets": "Widgets",
"go-neb": "go-neb", "go-neb": "go-neb",
"Custom Bots": "Custom Bots", "Custom Bots": "Custom Bots",
"Bridges": "Bridges", "Bridges": "Bridges",
"Sticker Packs": "Sticker Packs", "Sticker Packs": "Sticker Packs",
"Terms of Service": "Terms of Service", "Terms of Service": "Terms of Service",
"Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.": "Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.", "Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.": "Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.",
"Name": "Name", "Name": "Name",
"Description": "Description", "Description": "Description",
"Actions": "Actions", "Actions": "Actions",
"No bridges.": "No bridges.", "No bridges.": "No bridges.",
"matrix-appservice-gitter": "matrix-appservice-gitter", "matrix-hookshot": "matrix-hookshot",
"is a Gitter bridge that supports bridging Gitter rooms to Matrix. Users on Matrix are represented as a single bot user in Gitter, however Gitter users are represented as real-looking Matrix users in the room.": "is a Gitter bridge that supports bridging Gitter rooms to Matrix. Users on Matrix are represented as a single bot user in Gitter, however Gitter users are represented as real-looking Matrix users in the room.", "is a multi-purpose bridge which supports Github as an integration. If enabled in the configuration, it can be used here to offer a UI for setting up a room to pipe to a repository.": "is a multi-purpose bridge which supports Github as an integration. If enabled in the configuration, it can be used here to offer a UI for setting up a room to pipe to a repository.",
"No bridge configurations.": "No bridge configurations.", "No bridge configurations.": "No bridge configurations.",
"Add matrix.org's bridge": "Add matrix.org's bridge", "Add self-hosted bridge": "Add self-hosted bridge",
"Add self-hosted bridge": "Add self-hosted bridge", "self-hosted Github bridge": "self-hosted Github bridge",
"self-hosted Gitter bridge": "self-hosted Gitter bridge ", "Self-hosted Github bridges must have": "Self-hosted Github bridges must have",
"Self-hosted Gitter bridges already have provisioning enabled. Be careful not to expose the API to the public internet.": "Self-hosted Gitter bridges already have provisioning enabled. Be careful not to expose the API to the public internet.", "provisioning": "provisioning",
"Provisioning URL": "Provisioning URL", "enabled in the configuration.": "enabled in the configuration.",
"The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.": "The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.", "Provisioning URL": "Provisioning URL",
"Save": "Save", "The provisioning URL for the bridge. This is the specific address for the bridge given in the configuration.": "The provisioning URL for the bridge. This is the specific address for the bridge given in the configuration.",
"Cancel": "Cancel", "Shared Secret": "Shared Secret",
"Add a new self-hosted IRC Bridge": "Add a new self-hosted IRC Bridge ", "The shared secret defined in the configuration for provisioning.": "The shared secret defined in the configuration for provisioning.",
"Self-hosted IRC bridges must have": "Self-hosted IRC bridges must have", "Save": "Save",
"provisioning": "provisioning", "Cancel": "Cancel",
"enabled in the configuration.": "enabled in the configuration.", "Add a new self-hosted IRC Bridge": "Add a new self-hosted IRC Bridge ",
"The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.": "The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.", "Self-hosted IRC bridges must have": "Self-hosted IRC bridges must have",
"matrix-appservice-irc": "matrix-appservice-irc", "The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.": "The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.",
"is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.": "is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.", "matrix-appservice-irc": "matrix-appservice-irc",
"Enabled Networks": "Enabled Networks", "is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.": "is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.",
"This bridge is offline or unavailable.": "This bridge is offline or unavailable.", "Enabled Networks": "Enabled Networks",
"Network": "Network", "This bridge is offline or unavailable.": "This bridge is offline or unavailable.",
"Enabled": "Enabled", "Add matrix.org's bridge": "Add matrix.org's bridge",
"Close": "Close", "Network": "Network",
"self-hosted Slack bridge": "self-hosted Slack bridge ", "Enabled": "Enabled",
"Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.": "Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.", "Close": "Close",
"matrix-appservice-slack": "matrix-appservice-slack", "self-hosted Slack bridge": "self-hosted Slack bridge ",
"is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.": "is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.", "Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.": "Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.",
"self-hosted Telegram bridge": "self-hosted Telegram bridge ", "The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.": "The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.",
"Self-hosted Telegram bridges must have": "Self-hosted Telegram bridges must have", "matrix-appservice-slack": "matrix-appservice-slack",
"The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.": "The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.", "is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.": "is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.",
"Shared Secret": "Shared Secret", "self-hosted Telegram bridge": "self-hosted Telegram bridge ",
"The shared secret defined in the configuration for provisioning.": "The shared secret defined in the configuration for provisioning.", "Self-hosted Telegram bridges must have": "Self-hosted Telegram bridges must have",
"Promote Telegram Puppeting": "Promote Telegram Puppeting", "The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.": "The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.",
"If enabled, Dimension will recommend that users log in to their Telegram accounts.": "If enabled, Dimension will recommend that users log in to their Telegram accounts.", "Promote Telegram Puppeting": "Promote Telegram Puppeting",
"Promote Matrix Puppeting": "Promote Matrix Puppeting", "If enabled, Dimension will recommend that users log in to their Telegram accounts.": "If enabled, Dimension will recommend that users log in to their Telegram accounts.",
"If enabled, Dimension will recommend that users log in to their Matrix accounts.": "If enabled, Dimension will recommend that users log in to their Matrix accounts.", "Promote Matrix Puppeting": "Promote Matrix Puppeting",
"mautrix-telegram": "mautrix-telegram", "If enabled, Dimension will recommend that users log in to their Matrix accounts.": "If enabled, Dimension will recommend that users log in to their Matrix accounts.",
"is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.": "is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.", "mautrix-telegram": "mautrix-telegram",
"Enabled Features": "Enabled Features", "is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.": "is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.",
"self-hosted webhook bridge": "self-hosted webhook bridge ", "Enabled Features": "Enabled Features",
"Self-hosted webhook bridges must have": "Self-hosted webhook bridges must have", "self-hosted webhook bridge": "self-hosted webhook bridge ",
"The public URL for the bridge.": "The public URL for the bridge.", "Self-hosted webhook bridges must have": "Self-hosted webhook bridges must have",
"The provisioning secret defined in the configuration.": "The provisioning secret defined in the configuration.", "The public URL for the bridge.": "The public URL for the bridge.",
"matrix-appservice-webhooks": "matrix-appservice-webhooks", "The provisioning secret defined in the configuration.": "The provisioning secret defined in the configuration.",
"provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.": "provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.", "matrix-appservice-webhooks": "matrix-appservice-webhooks",
"custom bot": "", "provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.": "provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.",
"The user ID that Dimension will invite to rooms.": "The user ID that Dimension will invite to rooms.", "custom bot": "custom bot",
"A few words here will help people understand what the bot does.": "A few words here will help people understand what the bot does.", "The user ID that Dimension will invite to rooms.": "The user ID that Dimension will invite to rooms.",
"Display Name": "Display Name", "A few words here will help people understand what the bot does.": "A few words here will help people understand what the bot does.",
"This is the name Dimension will use to tell users which bot this is.": "This is the name Dimension will use to tell users which bot this is.", "Display Name": "Display Name",
"This can either be an MXC URI or a plain URL.": "This can either be an MXC URI or a plain URL.", "This is the name Dimension will use to tell users which bot this is.": "This is the name Dimension will use to tell users which bot this is.",
"This is used by Dimension to force the bot to leave the room when the user removes the bot.": "This is used by Dimension to force the bot to leave the room when the user removes the bot.", "This can either be an MXC URI or a plain URL.": "This can either be an MXC URI or a plain URL.",
"Learn more about access tokens.": "Learn more about access tokens.", "This is used by Dimension to force the bot to leave the room when the user removes the bot.": "This is used by Dimension to force the bot to leave the room when the user removes the bot.",
"Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.": "Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.", "Learn more about access tokens.": "Learn more about access tokens.",
"No custom bots.": "No custom bots.", "Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.": "Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.",
"Add custom bot": "Add custom bot", "No custom bots.": "No custom bots.",
"Custom bots": "Custom bots", "Add custom bot": "Add custom bot",
"Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.": "Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.", "Custom bots": "Custom bots",
"Administrators": "Administrators", "Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.": "Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.",
"Widget Blacklist": "Widget Blacklist", "Administrators": "Administrators",
"Homeserver": "Homeserver", "Widget Blacklist": "Widget Blacklist",
"Federation URL": "Federation URL", "Homeserver": "Homeserver",
"Federation Hostname": "Federation Hostname", "Federation URL": "Federation URL",
"Client/Server URL": "Client/Server URL", "Federation Hostname": "Federation Hostname",
"Utility User ID": "Utility User ID", "Client/Server URL": "Client/Server URL",
"Sessions": "Settings", "Utility User ID": "Utility User ID",
"Tokens registered": "Tokens registered", "Sessions": "Settings",
"Logout Everyone": "Logout Everyone", "Tokens registered": "Tokens registered",
"Configuration": "Configuration", "Logout Everyone": "Logout Everyone",
"Logout confirmation": "Logout confirmation", "Configuration": "Configuration",
"Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.": "Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.", "Logout confirmation": "Logout confirmation",
"Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.": "Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.", "Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.": "Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.",
"User Prefix": "User Prefix", "Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.": "Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.",
"This is the prefix used for all bot users.": "This is the prefix used for all bot users.", "User Prefix": "User Prefix",
"API URL": "API URL", "This is the prefix used for all bot users.": "This is the prefix used for all bot users.",
"The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.": "The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.", "API URL": "API URL",
"New self-hosted go-neb": "New self-hosted go-neb", "The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.": "The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.",
"go-neb appservice configuration": "go-neb appservice configuration", "New self-hosted go-neb": "New self-hosted go-neb",
"Copy and paste this configuration to": "", "go-neb appservice configuration": "go-neb appservice configuration",
"on your homeserver and register it as an application service.": "", "Copy and paste this configuration to": "Copy and paste this configuration to",
"Test Configuration": "Test Configuration", "on your homeserver and register it as an application service.": "on your homeserver and register it as an application service.",
"Giphy Configuration": "Giphy Configuration", "Test Configuration": "Test Configuration",
"Api Key": "Api Key", "Giphy Configuration": "Giphy Configuration",
"The API key from": "The API key from", "Api Key": "Api Key",
"Image Size": "Image Size", "The API key from": "The API key from",
"GIFs can be large, and sometimes it is more desirable to have them downsized.": "GIFs can be large, and sometimes it is more desirable to have them downsized.", "Image Size": "Image Size",
"Use downsized images": "Use downsized images", "GIFs can be large, and sometimes it is more desirable to have them downsized.": "GIFs can be large, and sometimes it is more desirable to have them downsized.",
"Google Configuration": "Google Configuration", "Use downsized images": "Use downsized images",
"The API key for your Google Application.": "The API key for your Google Application.", "Google Configuration": "Google Configuration",
"The search engine ID": "The search engine ID", "The API key for your Google Application.": "The API key for your Google Application.",
"Guggy Configuration": "Guggy Configuration", "Search Engine ID": "Search Engine ID",
"The API key for": "The API key for", "The search engine ID": "The search engine ID",
"Imgur Configuration": "Imgur Configuration", "Guggy Configuration": "Guggy Configuration",
"Client ID": "Client ID", "The API key for": "The API key for",
"The client ID of your": "The client ID of your", "Imgur Configuration": "Imgur Configuration",
"Imgur Application": "Imgur Application", "Client ID": "Client ID",
"Client Secret": "Client Secret", "The client ID of your": "The client ID of your",
"The client secret of your": "The client secret of your", "Imgur Application": "Imgur Application",
"go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.": "go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.", "Client Secret": "Client Secret",
"is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).": "<a href='https://github.com/matrix-org/go-neb' target='_blank'>go-neb</a> is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).", "The client secret of your": "The client secret of your",
"Enabled Bots": "Enabled Bots", "go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.": "go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.",
"No go-neb configurations.": "No go-neb configurations.", "is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).": "<a href='https://github.com/matrix-org/go-neb' target='_blank'>go-neb</a> is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).",
"Add matrix.org's go-neb": "Add matrix.org's go-neb", "Enabled Bots": "Enabled Bots",
"Add self-hosted go-neb": "Add self-hosted go-neb", "No go-neb configurations.": "No go-neb configurations.",
"go-neb configurations": "go-neb configurations", "Add matrix.org's go-neb": "Add matrix.org's go-neb",
"Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.": "Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.", "Add self-hosted go-neb": "Add self-hosted go-neb",
"Import from Telegram": "Import from Telegram", "go-neb configurations": "go-neb configurations",
"Author": "Author", "Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.": "Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.",
"License": "License", "Import from Telegram": "Import from Telegram",
"No sticker packs installed.": "No sticker packs installed.", "Author": "Author",
"Dimension": "Dimension", "License": "License",
"version": "", "No sticker packs installed.": "No sticker packs installed.",
"The translated name of your policy": "The translated name of your policy", "Dimension": "Dimension",
"Policy text": "Policy text", "version": "version",
"This is where you put your policy's content.": "This is where you put your policy's content.", "The translated name of your policy": "The translated name of your policy",
"Create draft": "Create draft", "Policy text": "Policy text",
"Save draft": "Save draft", "This is where you put your policy's content.": "This is where you put your policy's content.",
"Publish": "Publish", "Create draft": "Create draft",
"Publish policy": "Publish policy", "Save draft": "Save draft",
"Version number": "Version number", "Publish": "Publish",
"The version number of this policy": "The version number of this policy", "Publish policy": "Publish policy",
"Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.": "Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.", "Version number": "Version number",
"Policy Name": "Policy Name", "The version number of this policy": "The version number of this policy",
"Version": "Version", "Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.": "Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.",
"No policies written.": "No policies written.", "Policy Name": "Policy Name",
"New draft policy": "New draft policy", "Version": "Version",
"Etherpad Widget Configuration": "Etherpad Widget Configuration", "No policies written.": "No policies written.",
"Default Pad URL Template": "Default Pad URL Template", "New draft policy": "New draft policy",
"$padName and $roomId will be replaced during creation to help create a unique pad URL.": "$padName and $roomId will be replaced during creation to help create a unique pad URL.", "Etherpad Widget Configuration": "Etherpad Widget Configuration",
"Jitsi Widget Configuration": "Jitsi Widget Configuration", "Default Pad URL Template": "Default Pad URL Template",
"Jitsi Domain": "Jitsi Domain", "$padName and $roomId will be replaced during creation to help create a unique pad URL.": "$padName and $roomId will be replaced during creation to help create a unique pad URL.",
"This is the domain that is used to host the conference.": "This is the domain that is used to host the conference.", "Jitsi Widget Configuration": "Jitsi Widget Configuration",
"Use this domain as the default conference domain": "Use this domain as the default conference domain", "Jitsi Domain": "Jitsi Domain",
"Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.": "Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.", "This is the domain that is used to host the conference.": "This is the domain that is used to host the conference.",
"Jitsi Script URL": "Jitsi Script URL", "Use this domain as the default conference domain": "Use this domain as the default conference domain",
"This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.": "This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.", "Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.": "Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.",
"Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.": "Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.", "Jitsi Script URL": "Jitsi Script URL",
"Bridge to Gitter": "Bridge to Gitter", "This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.": "This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.",
"This room is bridged to on Gitter": "This room is bridged to", "Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.": "Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.",
"on Gitter": "on Gitter", "Bridge to Github": "Bridge to Github",
"Unbridge": "Unbridge", "In order to bridge to Github, you'll need to authorize the bridge to access your organization(s). Please click the button below to do so.": "In order to bridge to Github, you'll need to authorize the bridge to access your organization(s). Please click the button below to do so.",
"Gitter Room": "Gitter Room", "Organization": "Organization",
"Add an IRC channel": "Add an IRC channel", "Repository": "Repository",
"Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.": "Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.", "Add an IRC channel": "Add an IRC channel",
"Channel Name": "Channel Name", "Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.": "Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.",
"Next": "Next", "Channel Name": "Channel Name",
"Operator": "Operator", "Next": "Next",
"The person selected here will be asked to approve or deny the bridge request.": "The person selected here will be asked to approve or deny the bridge request.", "Operator": "Operator",
"Request Bridge": "Request Bridge", "The person selected here will be asked to approve or deny the bridge request.": "The person selected here will be asked to approve or deny the bridge request.",
"IRC Networks": "IRC Networks", "Request Bridge": "Request Bridge",
"Channel": "Channel", "IRC Networks": "IRC Networks",
"No bridged channels": "No bridged channels", "Channel": "Channel",
"Remove": "Remove", "No bridged channels": "No bridged channels",
"Bridge to Slack": "Bridge to Slack", "Remove": "Remove",
"This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.": "This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.", "Bridge to Slack": "Bridge to Slack",
"In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.": "In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.", "This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.": "This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.",
"Team": "Team", "Unbridge": "Unbridge",
"Telegram chat is already bridged": "Telegram chat is already bridged", "In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.": "In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.",
"You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?": "You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?", "Team": "Team",
"Unbridge and continue": "Unbridge and continue", "Telegram chat is already bridged": "Telegram chat is already bridged",
"No, don't bridge": "No, don't bridge", "You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?": "You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?",
"That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.": "That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.", "Unbridge and continue": "Unbridge and continue",
"Bridge to Telegram": "Bridge to Telegram", "No, don't bridge": "No, don't bridge",
"This room is bridged to on Telegram": "This room is bridged to", "That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.": "That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.",
"on Telegram": "on Telegram", "Bridge to Telegram": "Bridge to Telegram",
"You do not have the necessary permissions in this room to unbridge the channel.": "You do not have the necessary permissions in this room to unbridge the channel.", "This room is bridged to on Telegram": "This room is bridged to",
"After inviting": "After inviting", "on Telegram": "on Telegram",
"to your Telegram chat, run the command": "to your Telegram chat, run the command", "You do not have the necessary permissions in this room to unbridge the channel.": "You do not have the necessary permissions in this room to unbridge the channel.",
"in the Telegram room to get the chat ID.": "in the Telegram room to get the chat ID.", "After inviting": "After inviting",
"Add a new webhook": "Add a new webhook", "to your Telegram chat, run the command": "to your Telegram chat, run the command",
"Webhook Name": "Webhook Name", "in the Telegram room to get the chat ID.": "in the Telegram room to get the chat ID.",
"Create": "Create", "Add a new webhook": "Add a new webhook",
"Type": "Type", "Webhook Name": "Webhook Name",
"No webhooks": "No webhooks", "Create": "Create",
"No name": "No name", "Type": "Type",
"Delete": "Delete", "No webhooks": "No webhooks",
"Feeds": "Feeds", "No name": "No name",
"Added by": "Added by", "Delete": "Delete",
"Add": "Add", "Feeds": "Feeds",
".travis.yml configuration and template information": ".travis.yml configuration and template information", "Added by": "Added by",
"The following section needs to be added to your": "", "Add": "Add",
"file in your repositories:": "", ".travis.yml configuration and template information": ".travis.yml configuration and template information",
"The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.": "The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.", "The following section needs to be added to your": "The following section needs to be added to your",
"The repository identifier": "The repository identifier", "file in your repositories:": "file in your repositories:",
"The repository name": "The repository name", "The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.": "The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.",
"The build number": "The build number", "The repository identifier": "The repository identifier",
"The build ID": "The build ID", "The repository name": "The repository name",
"The branch name": "The branch name", "The build number": "The build number",
"A short version of the commit SHA": "A short version of the commit SHA", "The build ID": "The build ID",
"The first line of the commit message": "The first line of the commit message", "The branch name": "The branch name",
"The full commit message": "The full commit message", "A short version of the commit SHA": "A short version of the commit SHA",
"The author of the commit": "The author of the commit", "The first line of the commit message": "The first line of the commit message",
"The result of the build": "<code> '%result' </code> - The result of the build", "The full commit message": "The full commit message",
"The message from Travis CI about the build": "The message from Travis CI about the build", "The author of the commit": "The author of the commit",
"The total duration of all builds in the matrix": "The total duration of all builds in the matrix", "The result of the build": "<code> '%result' </code> - The result of the build",
"The time it took to run the build": "The time it took to run the build", "The message from Travis CI about the build": "The message from Travis CI about the build",
"A URL to see the changes which triggered the build": "A URL to see the changes which triggered the build", "The total duration of all builds in the matrix": "The total duration of all builds in the matrix",
"A URL to see the build information": "A URL to see the build information", "The time it took to run the build": "The time it took to run the build",
"Repositories": "Repositories", "A URL to see the changes which triggered the build": "A URL to see the changes which triggered the build",
"Repository": "", "A URL to see the build information": "A URL to see the build information",
"Template": "Template", "Repositories": "Repositories",
"Sticker packs are not enabled on this Dimension instance.": "Sticker packs are not enabled on this Dimension instance.", "Template": "Template",
"Start a conversation with": "Start a conversation with", "Sticker packs are not enabled on this Dimension instance.": "Sticker packs are not enabled on this Dimension instance.",
"to create your own stickerpack.": "to create your own stickerpack.", "Start a conversation with": "Start a conversation with",
"Add stickerpack": "Add stickerpack", "to create your own stickerpack.": "to create your own stickerpack.",
"Created by": "Created by", "Add stickerpack": "Add stickerpack",
"under": "under", "Created by": "Created by",
"BigBlueButton Meeting URL": "", "under": "under",
"Add Widget": "Add Widget", "BigBlueButton Meeting URL": "BigBlueButton Meeting URL",
"Save Widget": "Save Widget", "Add Widget": "Add Widget",
"Remove Widget": "Remove Widget", "Save Widget": "Save Widget",
"Widget Name": "Widget Name", "Remove Widget": "Remove Widget",
"Widget URL": "Widget URL", "Widget Name": "Widget Name",
"Pad Name": "Pad Name", "Widget URL": "Widget URL",
"Pad URL": "Pad URL", "Pad Name": "Pad Name",
"Shared Calendar ID": "Shared Calendar ID", "Pad URL": "Pad URL",
"Document URL": "Document URL", "Shared Calendar ID": "Shared Calendar ID",
"Grafana URL": "Grafana URL", "Document URL": "Document URL",
"To get a URL, go to Grafana and click 'share' on a graph.": "To get a URL, go to Grafana and click 'share' on a graph.", "Grafana URL": "Grafana URL",
"Conference URL": "Conference URL", "To get a URL, go to Grafana and click 'share' on a graph.": "To get a URL, go to Grafana and click 'share' on a graph.",
" Spotify URI": "", "Conference URL": "Conference URL",
"Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.": "Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.", " Spotify URI": " Spotify URI",
"Trading Pair": "Trading Pair", "Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.": "Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.",
"Interval": "Interval", "Trading Pair": "Trading Pair",
"Whiteboard Name": "Whiteboard Name", "Interval": "Interval",
"Whiteboard URL": "Whiteboard URL", "Whiteboard Name": "Whiteboard Name",
"Video URL": "Video URL", "Whiteboard URL": "Whiteboard URL",
"An open source integration manager for Matrix": "An open source integration manager for Matrix", "Video URL": "Video URL",
"Self-host your favourite bots, bridges, and widgets.": "Self-host your favourite bots, bridges, and widgets.", "An open source integration manager for Matrix": "An open source integration manager for Matrix",
"source": "source", "Self-host your favourite bots, bridges, and widgets.": "Self-host your favourite bots, bridges, and widgets.",
"Try it out or": "Try it out or", "source": "source",
"run your own": "run your own", "Try it out or": "Try it out or",
"Visit": "Visit", "run your own": "run your own",
"and log in with your Matrix account or point your Element": "and log in with your Matrix account or point your Element", "Visit": "Visit",
"at our servers:": "at our servers:", "and log in with your Matrix account or point your Element": "and log in with your Matrix account or point your Element",
"Add utility for everyone in your room by embedding an application.": "Add utility for everyone in your room by embedding an application.", "at our servers:": "at our servers:",
"Notes": "Notes", "Add utility for everyone in your room by embedding an application.": "Add utility for everyone in your room by embedding an application.",
"Google Calendar": "Google Calendar", "Notes": "Notes",
"Custom Widget": "Custom Widget", "Google Calendar": "Google Calendar",
"Bots bring entertainment or productivity to the room. They're here to help at your command.": "Bots bring entertainment or productivity to the room. They're here to help at your command.", "Custom Widget": "Custom Widget",
"Guggy": "Guggy", "Bots bring entertainment or productivity to the room. They're here to help at your command.": "Bots bring entertainment or productivity to the room. They're here to help at your command.",
"Giphy": "Giphy", "Guggy": "Guggy",
"Imgur": "Imgur", "Giphy": "Giphy",
"Google Image Search": "Google Image Search", "Imgur": "Imgur",
"Wikipedia": "Wikipedia", "Google Image Search": "Google Image Search",
"Travis CI": "Travis CI", "Wikipedia": "Wikipedia",
"RSS Notifications": "RSS Notifications", "Travis CI": "Travis CI",
"Echo": "Echo", "RSS Notifications": "RSS Notifications",
"Bring the outside world into your room with bridges.": "Bring the outside world into your room with bridges.", "Echo": "Echo",
"Stickers": "Stickers", "Bring the outside world into your room with bridges.": "Bring the outside world into your room with bridges.",
"Have some fun and post a sticker.": "Have some fun and post a sticker.", "Stickers": "Stickers",
"Huskies": "Huskies", "Have some fun and post a sticker.": "Have some fun and post a sticker.",
"Cats": "Cats", "Huskies": "Huskies",
"Cat Faces": "Cat Faces", "Cats": "Cats",
"Loading Artist": "Loading Artist", "Cat Faces": "Cat Faces",
"source on GitHub": "source on GitHub", "Loading Artist": "Loading Artist",
"Welcome to Dimension!": "Welcome to Dimension!", "source on GitHub": "source on GitHub",
"Join": "Join", "Welcome to Dimension!": "Welcome to Dimension!",
"for news and updates. Don't forget to star the repository on": "for news and updates. Don't forget to star the repository on", "Join": "Join",
"Here's the configuration options you'll need to update in your Element": "Here's the configuration options you'll need to update in your Element", "for news and updates. Don't forget to star the repository on": "for news and updates. Don't forget to star the repository on",
"Configuring integrations": "Configuring integrations", "Here's the configuration options you'll need to update in your Element": "Here's the configuration options you'll need to update in your Element",
"If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon": "If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon", "The location of": "The location of ",
"in the top right is where you can configure your bots, bridges, and widgets.": "in the top right is where you can configure your bots, bridges, and widgets.", "differs depending on whether the": " differs depending on whether the",
"Could not connect to integrations server error": "Could not connect to integrations server error", "or": " or ",
"When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in": "When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in", "version of Element is used.": " version of Element is used.",
"on Matrix, here's a few things to check:": "on Matrix, here's a few things to check:", "Configuring integrations": "Configuring integrations",
"Verify the homeserver configuration in Dimension.": "Verify the homeserver configuration in Dimension.", "If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon": "If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon",
"The name, client/server URL, and access token all need to be valid and directed at your homeserver.": "The name, client/server URL, and access token all need to be valid and directed at your homeserver.", "in the top right is where you can configure your bots, bridges, and widgets.": "in the top right is where you can configure your bots, bridges, and widgets.",
"Verify federation is enabled on your homeserver.": "Verify federation is enabled on your homeserver.", "Could not connect to integrations server error": "Could not connect to integrations server error",
"Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.": "Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.", "When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in": "When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in",
"Verify that federation is working on your homeserver.": "Verify that federation is working on your homeserver.", "on Matrix, here's a few things to check:": "on Matrix, here's a few things to check:",
"Using tools like the": "Using tools like the", "Verify the homeserver configuration in Dimension.": "Verify the homeserver configuration in Dimension.",
"federation tester": "federation tester", "The name, client/server URL, and access token all need to be valid and directed at your homeserver.": "The name, client/server URL, and access token all need to be valid and directed at your homeserver.",
", make sure that federation is working on your homeserver.": ", make sure that federation is working on your homeserver.", "Verify federation is enabled on your homeserver.": "Verify federation is enabled on your homeserver.",
"Looking for your sticker packs?": "Looking for your sticker packs?", "Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.": "Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.",
"Click here": "Click here", "Verify that federation is working on your homeserver.": "Verify that federation is working on your homeserver.",
"This room is encrypted": "This room is encrypted", "Using tools like the": "Using tools like the",
"Integrations are not encrypted!": "Integrations are not encrypted!", "federation tester": "federation tester",
"This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.": "This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.", ", make sure that federation is working on your homeserver.": ", make sure that federation is working on your homeserver.",
"There are currently no integrations which support encrypted rooms. Sorry about that!": "There are currently no integrations which support encrypted rooms. Sorry about that!", "Looking for your sticker packs?": "Looking for your sticker packs?",
"No integrations available": "No integrations available", "Click here": "Click here",
"This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.": "This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.", "This room is encrypted": "This room is encrypted",
"BigBlueButton Conference": "BigBlueButton Conference", "Integrations are not encrypted!": "Integrations are not encrypted!",
"Join Conference": "Join Conference", "This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.": "This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.",
"Sorry, this content cannot be embedded": "Sorry, this content cannot be embedded", "There are currently no integrations which support encrypted rooms. Sorry about that!": "There are currently no integrations which support encrypted rooms. Sorry about that!",
"Start camera:": "", "No integrations available": "No integrations available",
"You": "You", "This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.": "This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.",
"Integrations": "Integrations", "BigBlueButton Conference": "BigBlueButton Conference",
"Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.": "Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.", "Join Conference": "Join Conference",
"Check connection": "Check connection", "Sorry, this content cannot be embedded": "Sorry, this content cannot be embedded",
"Click to start OpenID auth": "Click to start OpenID auth", "Start camera:": "Start camera:",
"User ID:": "User ID:", "You": "You",
"You have blocked this widget from receiving credentials.": "You have blocked this widget from receiving credentials.", "Integrations": "Integrations",
"An error has occurred - see logs for details": "An error has occurred - see logs for details", "Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.": "Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.",
"There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.": "There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.", "Check connection": "Check connection",
"You have no sticker packs.": "You have no sticker packs.", "Click to start OpenID auth": "Click to start OpenID auth",
"Add some stickers": "Add some stickers", "User ID:": "User ID:",
"Failed to load bridges": "Failed to load bridges", "You have blocked this widget from receiving credentials.": "You have blocked this widget from receiving credentials.",
"Error loading bridges": "Error loading bridges", "An error has occurred - see logs for details": "An error has occurred - see logs for details",
"matrix.org's Gitter bridge added": "matrix.org's Gitter bridge added", "There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.": "There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.",
"Error adding matrix.org's Gitter Bridge": "Error adding matrix.org's Gitter Bridge", "You have no sticker packs.": "You have no sticker packs.",
"Error creating matrix.org's Gitter Bridge": "Error creating matrix.org's Gitter Bridge", "Add some stickers": "Add some stickers",
"Failed to get an update Gitter bridge list": "Failed to get an update Gitter bridge list", "Failed to load bridges": "Failed to load bridges",
"Gitter bridge added": "Gitter bridge added", "Error loading bridges": "Error loading bridges",
"Failed to create Gitter bridge": "Failed to create Gitter bridge", "Failed to get an updated Github bridge list": "Failed to get an updated Github bridge list",
"Gitter bridge updated": "Gitter bridge updated", "Github bridge added": "Github bridge added",
"Failed to update Gitter bridge": "Failed to update Gitter bridge", "Failed to create Github bridge": "Failed to create Github bridge",
"IRC Bridge added": "IRC Bridge added", "Github bridge updated": "Github bridge updated",
"Failed to create IRC bridge": "Failed to create IRC bridge", "Failed to update Github bridge": "Failed to update Github bridge",
"Click the pencil icon to enable networks.": "Click the pencil icon to enable networks.", "IRC Bridge added": "IRC Bridge added",
"matrix.org's IRC bridge added": "matrix.org's IRC bridge added", "Failed to create IRC bridge": "Failed to create IRC bridge",
"Error adding matrix.org's IRC Bridge": "Error adding matrix.org's IRC Bridge", "Click the pencil icon to enable networks.": "Click the pencil icon to enable networks.",
"Error creating matrix.org's IRC Bridge": "Error creating matrix.org's IRC Bridge", "matrix.org's IRC bridge added": "matrix.org's IRC bridge added",
"Failed to get an update IRC bridge list": "Failed to get an update IRC bridge list", "Error adding matrix.org's IRC Bridge": "Error adding matrix.org's IRC Bridge",
"disabled": "disabled", "Error creating matrix.org's IRC Bridge": "Error creating matrix.org's IRC Bridge",
"Failed to update network": "Failed to update network", "Failed to get an update IRC bridge list": "Failed to get an update IRC bridge list",
"Slack bridge added": "Slack bridge added", "disabled": "disabled",
"Failed to create Slack bridge": "Failed to create Slack bridge", "Failed to update network": "Failed to update network",
"Slack bridge updated": "Slack bridge updated", "Slack bridge added": "Slack bridge added",
"Failed to update Slack bridge": "Failed to update Slack bridge", "Failed to create Slack bridge": "Failed to create Slack bridge",
"matrix.org's Slack bridge added": "matrix.org's Slack bridge added", "Slack bridge updated": "Slack bridge updated",
"Error adding matrix.org's Slack Bridge": "Error adding matrix.org's Slack Bridge", "Failed to update Slack bridge": "Failed to update Slack bridge",
"Error creating matrix.org's Slack Bridge": "Error creating matrix.org's Slack Bridge", "matrix.org's Slack bridge added": "matrix.org's Slack bridge added",
"Failed to get an update Slack bridge list": "Failed to get an update Slack bridge list", "Error adding matrix.org's Slack Bridge": "Error adding matrix.org's Slack Bridge",
"Telegram bridge added": "Telegram bridge added", "Error creating matrix.org's Slack Bridge": "Error creating matrix.org's Slack Bridge",
"Failed to create Telegram bridge": "Failed to create Telegram bridge", "Failed to get an update Slack bridge list": "Failed to get an update Slack bridge list",
"Telegram bridge updated": "Telegram bridge updated", "Telegram bridge added": "Telegram bridge added",
"Failed to update Telegram bridge": "Failed to update Telegram bridge", "Failed to create Telegram bridge": "Failed to create Telegram bridge",
"Failed to get an update Telegram bridge list": "Failed to get an update Telegram bridge list", "Telegram bridge updated": "Telegram bridge updated",
"Webhook bridge added": "Webhook bridge added", "Failed to update Telegram bridge": "Failed to update Telegram bridge",
"Failed to create Webhook bridge": "Failed to create Webhook bridge", "Failed to get an update Telegram bridge list": "Failed to get an update Telegram bridge list",
"Webhook bridge updated": "Webhook bridge updated", "Webhook bridge added": "Webhook bridge added",
"Failed to update Webhook bridge": "Failed to update Webhook bridge", "Failed to create Webhook bridge": "Failed to create Webhook bridge",
"Failed to get an update Webhooks bridge list": "Failed to get an update Webhooks bridge list", "Webhook bridge updated": "Webhook bridge updated",
"Please enter a name for the bot": "Please enter a name for the bot", "Failed to update Webhook bridge": "Failed to update Webhook bridge",
"Please enter an avatar URL for the bot": "Please enter an avatar URL for the bot", "Failed to get an update Webhooks bridge list": "Failed to get an update Webhooks bridge list",
"Please enter a user ID for the bot": "Please enter a user ID for the bot", "Please enter a name for the bot": "Please enter a name for the bot",
"Please enter a description for the bot": "Please enter a description for the bot", "Please enter an avatar URL for the bot": "Please enter an avatar URL for the bot",
"Please enter an access token for the bot": "Please enter an access token for the bot", "Please enter a user ID for the bot": "Please enter a user ID for the bot",
"Bot updated": "Bot updated", "Please enter a description for the bot": "Please enter a description for the bot",
"Error updating bot": "Error updating bot", "Please enter an access token for the bot": "Please enter an access token for the bot",
"Error loading go-neb configuration": "Error loading go-neb configuration", "Bot updated": "Bot updated",
"Failed to get an updated bot list": "Failed to get an updated bot list", "Error updating bot": "Error updating bot",
"Everyone has been logged out": "Everyone has been logged out", "Error loading go-neb configuration": "Error loading go-neb configuration",
"Error logging everyone out": "Error logging everyone out", "Failed to get an updated bot list": "Failed to get an updated bot list",
"New go-neb created": "New go-neb created", "Everyone has been logged out": "Everyone has been logged out",
"Error creating appservice": "Error creating appservice", "Error logging everyone out": "Error logging everyone out",
"Could not load appservice configuration": "Could not load appservice configuration", "New go-neb created": "New go-neb created",
"The appservice appears to be correctly set up": "The appservice appears to be correctly set up", "Error creating appservice": "Error creating appservice",
"The appservice is not correctly set up": "The appservice is not correctly set up", "Could not load appservice configuration": "Could not load appservice configuration",
"Error loading configuration": "Error loading configuration", "The appservice appears to be correctly set up": "The appservice appears to be correctly set up",
"Configuration updated": "Configuration updated", "The appservice is not correctly set up": "The appservice is not correctly set up",
"Error updating integration": "Error updating integration", "Error loading configuration": "Error loading configuration",
"Integration updated": "Integration updated", "Configuration updated": "Configuration updated",
"Failed to configure the integration": "Failed to configure the integration", "Error updating integration": "Error updating integration",
"Manual troubleshooting may be requred": "Manual troubleshooting may be requred", "Integration updated": "Integration updated",
"Could not get go-neb configuration": "Could not get go-neb configuration", "Failed to configure the integration": "Failed to configure the integration",
"matrix.org's go-neb added": "matrix.org's go-neb added", "Manual troubleshooting may be requred": "Manual troubleshooting may be requred",
"Click the pencil icon to enable the bots.": "Click the pencil icon to enable the bots.", "Could not get go-neb configuration": "Could not get go-neb configuration",
"Error adding matrix.org's go-neb": "Error adding matrix.org's go-neb", "matrix.org's go-neb added": "matrix.org's go-neb added",
"Error creating matrix.org go-neb": "Error creating matrix.org go-neb", "Click the pencil icon to enable the bots.": "Click the pencil icon to enable the bots.",
"Failed to load sticker packs": "Failed to load sticker packs", "Error adding matrix.org's go-neb": "Error adding matrix.org's go-neb",
"Sticker pack updated": "Sticker pack updated", "Error creating matrix.org go-neb": "Error creating matrix.org go-neb",
"Error updating sticker pack": "Error updating sticker pack", "Failed to load sticker packs": "Failed to load sticker packs",
"Telegram sticker pack imported": "Telegram sticker pack imported", "Sticker pack updated": "Sticker pack updated",
"Error importing sticker pack": "Error importing sticker pack", "Error updating sticker pack": "Error updating sticker pack",
"Failed to load policy": "Failed to load policy", "Telegram sticker pack imported": "Telegram sticker pack imported",
"Failed to load policies": "Failed to load policies", "Error importing sticker pack": "Error importing sticker pack",
"Policy published": "Policy published", "Failed to load policy": "Failed to load policy",
"Error publishing policy": "Error publishing policy", "Failed to load policies": "Failed to load policies",
"Please enter a name for all policies": "Please enter a name for all policies", "Policy published": "Policy published",
"Please enter text for all policies": "Please enter text for all policies", "Error publishing policy": "Error publishing policy",
"Draft saved": "Draft saved", "Please enter a name for all policies": "Please enter a name for all policies",
"Error saving policy": "Error saving policy", "Please enter text for all policies": "Please enter text for all policies",
"Draft created": "Draft created", "Draft saved": "Draft saved",
"Error creating document": "Error creating document", "Error saving policy": "Error saving policy",
"Please enter a version number": "Please enter a version number", "Draft created": "Draft created",
"Widget updated": "Widget updated", "Error creating document": "Error creating document",
"Error updating widget": "Error updating widget", "Please enter a version number": "Please enter a version number",
"Failed to load widgets": "Failed to load widgets", "Widget updated": "Widget updated",
"Error opening configuration page": "Error opening configuration page", "Error updating widget": "Error updating widget",
"Failed to load configuration": "Failed to load configuration", "Failed to load widgets": "Failed to load widgets",
"Error updating configuration": "Error updating configuration", "Error opening configuration page": "Error opening configuration page",
"Error inviting bridge": "Error inviting bridge", "Failed to load configuration": "Failed to load configuration",
"Bridge requested": "Bridge requested", "Error updating configuration": "Error updating configuration",
"Error requesting bridge": "Error requesting bridge", "Error inviting bridge": "Error inviting bridge",
"Bridge removed": "Bridge removed", "Bridge requested": "Bridge requested",
"Error removing bridge": "Error removing bridge", "Error requesting bridge": "Error requesting bridge",
"Please enter a channel name": "Please enter a channel name", "Bridge removed": "Bridge removed",
"Error loading channel operators": "Error loading channel operators", "Error removing bridge": "Error removing bridge",
"Failed to make the bridge an administrator": "Failed to make the bridge an administrator", "Please enter a channel name": "Please enter a channel name",
"Please ensure you are an 'Admin' for the room": "Please ensure you are an 'Admin' for the room", "Error loading channel operators": "Error loading channel operators",
"Link requested!": "Link requested!", "Failed to make the bridge an administrator": "Failed to make the bridge an administrator",
"The operator selected will have to approve the bridge for it to work": "The operator selected will have to approve the bridge for it to work", "Please ensure you are an 'Admin' for the room": "Please ensure you are an 'Admin' for the room",
"Failed to request a link": "Failed to request a link", "Link requested!": "Link requested!",
"Link removed": "Link removed", "The operator selected will have to approve the bridge for it to work": "The operator selected will have to approve the bridge for it to work",
"Failed to remove link": "Failed to remove link", "Failed to request a link": "Failed to request a link",
"Error getting Slack authorization information": "Error getting Slack authorization information", "Link removed": "Link removed",
"Error getting teams": "Error getting teams", "Failed to remove link": "Failed to remove link",
"Error getting channels for team": "Error getting channels for team", "Error getting Slack authorization information": "Error getting Slack authorization information",
"Bridge updated": "Bridge updated", "Error getting teams": "Error getting teams",
"Webhook created": "Webhook created", "Error getting channels for team": "Error getting channels for team",
"Error creating webhook": "Error creating webhook", "Bridge updated": "Bridge updated",
"Webhook deleted": "Webhook deleted", "Webhook created": "Webhook created",
"Error deleting webhook": "Error deleting webhook", "Error creating webhook": "Error creating webhook",
"Please enter a feed URL": "Please enter a feed URL", "Webhook deleted": "Webhook deleted",
"Please enter a repository": "Please enter a repository", "Error deleting webhook": "Error deleting webhook",
"was invited to the room": "was invited to the room", "Please enter a feed URL": "Please enter a feed URL",
"was removed from the room": " was removed from the room", "Please enter a repository": "Please enter a repository",
"Could not update integration status": "Could not update integration status", "was invited to the room": "was invited to the room",
"Stickerpack added": "Stickerpack added", "was removed from the room": " was removed from the room",
"Error adding stickerpack": "Error adding stickerpack", "Could not update integration status": "Could not update integration status",
"Stickers updated": "Stickers updated", "Stickerpack added": "Stickerpack added",
"Error updating stickers": "Error updating stickers", "Error adding stickerpack": "Error adding stickerpack",
"Please enter a URL for the widget": "Please enter a URL for the widget", "Stickers updated": "Stickers updated",
"Widget added!": "Widget added!", "Error updating stickers": "Error updating stickers",
"Widget updated!": "Widget updated!", "Please enter a URL for the widget": "Please enter a URL for the widget",
"Widget deleted!": "Widget deleted!", "Widget added!": "Widget added!",
"Please enter a video URL": "Please enter a video URL", "Widget updated!": "Widget updated!",
"Please enter a YouTube, Vimeo, or DailyMotion video URL": "Please enter a YouTube, Vimeo, or DailyMotion video URL", "Widget deleted!": "Widget deleted!",
"Unable to load Dimension - missing room ID or token.": "Unable to load Dimension - missing room ID or token.", "Please enter a video URL": "Please enter a video URL",
"Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!": "Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!", "Please enter a YouTube, Vimeo, or DailyMotion video URL": "Please enter a YouTube, Vimeo, or DailyMotion video URL",
"Unable to communicate with Dimension due to an unknown error.": "Unable to communicate with Dimension due to an unknown error.", "Unable to load Dimension - missing room ID or token.": "Unable to load Dimension - missing room ID or token.",
"You do not appear to have permission to modify widgets in this room": "You do not appear to have permission to modify widgets in this room", "Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!": "Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!",
"Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.": "Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.", "Unable to communicate with Dimension due to an unknown error.": "Unable to communicate with Dimension due to an unknown error.",
"This integration is offline or unavailable": "This integration is offline or unavailable", "You do not appear to have permission to modify widgets in this room": "You do not appear to have permission to modify widgets in this room",
"Could not communicate with Element": "Could not communicate with Element", "Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.": "Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.",
"The room must be": "The room must be", "This integration is offline or unavailable": "This integration is offline or unavailable",
"to use this integration": "to use this integration", "Could not communicate with Element": "Could not communicate with Element",
"You cannot modify widgets in this room": "You cannot modify widgets in this room", "You cannot modify widgets in this room": "You cannot modify widgets in this room",
"Error communicating with Element": "Error communicating with Element", "Error communicating with Element": "Error communicating with Element",
"Expected to not be able to send specific event types": "Expected to not be able to send specific event types", "Expected to not be able to send specific event types": "Expected to not be able to send specific event types",
"Expected to be able to send specific event types": "Expected to be able to send specific event types", "Expected to be able to send specific event types": "Expected to be able to send specific event types",
"Requirement": "Requirement ", "Requirement": "Requirement ",
"not found": " not found", "not found": " not found",
"Failed to take screenshot: iframe not supported": "Failed to take screenshot: iframe not supported", "Failed to take screenshot: iframe not supported": "Failed to take screenshot: iframe not supported",
"Failed to take screenshot": "Failed to take screenshot", "Failed to take screenshot": "Failed to take screenshot",
"Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.": "Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.", "Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.": "Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.",
"Please accept the prompt to verify your identity.": "Please accept the prompt to verify your identity.", "Please accept the prompt to verify your identity.": "Please accept the prompt to verify your identity.",
"You have blocked this widget from verifying your identity.": "You have blocked this widget from verifying your identity.", "You have blocked this widget from verifying your identity.": "You have blocked this widget from verifying your identity.",
"Checking connectivity to integration manager...": "Checking connectivity to integration manager...", "Checking connectivity to integration manager...": "Checking connectivity to integration manager...",
"Checking connectivity to homeserver...": "Checking connectivity to homeserver...", "Checking connectivity to homeserver...": "Checking connectivity to homeserver...",
"Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.": "Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.", "Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.": "Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.",
"You're all set! Click the button below to re-run the test.": "You're all set! Click the button below to re-run the test.", "You're all set! Click the button below to re-run the test.": "You're all set! Click the button below to re-run the test.",
"Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.": "Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.", "Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.": "Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.",
"Checking client version...": "Checking client version...", "Checking client version...": "Checking client version...",
"Your client is too old to use this widget, sorry": "Your client is too old to use this widget, sorry", "Your client is too old to use this widget, sorry": "Your client is too old to use this widget, sorry",
"Please accept the prompt to verify your identity": "Please accept the prompt to verify your identity", "Please accept the prompt to verify your identity": "Please accept the prompt to verify your identity",
"Error loading policy": "Error loading policy", "Error loading policy": "Error loading policy"
"The location of": "The location of ", }
"differs depending on whether the": " differs depending on whether the",
"or": " or ",
"version of Element is used.": " version of Element is used."
}

View File

@ -1,467 +1,463 @@
{ {
"Dashboard": "Dashboard", "Dashboard": "Dashboard",
"Widgets": "Widgets", "Widgets": "Widgets",
"go-neb": "go-neb", "go-neb": "go-neb",
"Custom Bots": "Custom Bots", "Custom Bots": "Custom Bots",
"Bridges": "Bridges", "Bridges": "Bridges",
"Sticker Packs": "Sticker Packs", "Sticker Packs": "Sticker Packs",
"Terms of Service": "Terms of Service", "Terms of Service": "Terms of Service",
"Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.": "Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.", "Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.": "Bridges provide a way for rooms to interact with and/or bring in events from a third party network. For example, an IRC bridge can allow IRC and matrix users to communicate with each other.",
"Name": "Name", "Name": "Name",
"Description": "Description", "Description": "Description",
"Actions": "Actions", "Actions": "Actions",
"No bridges.": "No bridges.", "No bridges.": "No bridges.",
"matrix-appservice-gitter": "matrix-appservice-gitter", "matrix-hookshot": "matrix-hookshot",
"is a Gitter bridge that supports bridging Gitter rooms to Matrix. Users on Matrix are represented as a single bot user in Gitter, however Gitter users are represented as real-looking Matrix users in the room.": "is a Gitter bridge that supports bridging Gitter rooms to Matrix. Users on Matrix are represented as a single bot user in Gitter, however Gitter users are represented as real-looking Matrix users in the room.", "is a multi-purpose bridge which supports Github as an integration. If enabled in the configuration, it can be used here to offer a UI for setting up a room to pipe to a repository.": "is a multi-purpose bridge which supports Github as an integration. If enabled in the configuration, it can be used here to offer a UI for setting up a room to pipe to a repository.",
"No bridge configurations.": "No bridge configurations.", "No bridge configurations.": "No bridge configurations.",
"Add matrix.org's bridge": "Add matrix.org's bridge", "Add self-hosted bridge": "Add self-hosted bridge",
"Add self-hosted bridge": "Add self-hosted bridge", "self-hosted Github bridge": "self-hosted Github bridge",
"self-hosted Gitter bridge": "self-hosted Gitter bridge", "Self-hosted Github bridges must have": "Self-hosted Github bridges must have",
"Self-hosted Gitter bridges already have provisioning enabled. Be careful not to expose the API to the public internet.": "Self-hosted Gitter bridges already have provisioning enabled. Be careful not to expose the API to the public internet.", "provisioning": "provisioning",
"Provisioning URL": "Provisioning URL", "enabled in the configuration.": "enabled in the configuration.",
"The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.": "The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.", "Provisioning URL": "Provisioning URL",
"Save": "Save", "The provisioning URL for the bridge. This is the specific address for the bridge given in the configuration.": "The provisioning URL for the bridge. This is the specific address for the bridge given in the configuration.",
"Cancel": "Cancel", "Shared Secret": "Shared Secret",
"Add a new self-hosted IRC Bridge": "Add a new self-hosted IRC Bridge", "The shared secret defined in the configuration for provisioning.": "The shared secret defined in the configuration for provisioning.",
"Self-hosted IRC bridges must have": "Self-hosted IRC bridges must have", "Save": "Save",
"provisioning": "provisioning", "Cancel": "Cancel",
"enabled in the configuration.": "enabled in the configuration.", "Add a new self-hosted IRC Bridge": "Add a new self-hosted IRC Bridge",
"The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.": "The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.", "Self-hosted IRC bridges must have": "Self-hosted IRC bridges must have",
"matrix-appservice-irc": "matrix-appservice-irc", "The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.": "The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.",
"is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.": "is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.", "matrix-appservice-irc": "matrix-appservice-irc",
"Enabled Networks": "Enabled Networks", "is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.": "is an IRC bridge that supports multiple IRC networks. Dimension is capable of using multiple IRC bridges to better distribute the load across multiple networks in large deployments.",
"This bridge is offline or unavailable.": "This bridge is offline or unavailable.", "Enabled Networks": "Enabled Networks",
"Network": "Network", "This bridge is offline or unavailable.": "This bridge is offline or unavailable.",
"Enabled": "Enabled", "Add matrix.org's bridge": "Add matrix.org's bridge",
"Close": "Close", "Network": "Network",
"self-hosted Slack bridge": "self-hosted Slack bridge", "Enabled": "Enabled",
"Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.": "Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.", "Close": "Close",
"matrix-appservice-slack": "matrix-appservice-slack", "self-hosted Slack bridge": "self-hosted Slack bridge",
"is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.": "is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.", "Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.": "Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.",
"self-hosted Telegram bridge": "self-hosted Telegram bridge", "The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.": "The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.",
"Self-hosted Telegram bridges must have": "Self-hosted Telegram bridges must have", "matrix-appservice-slack": "matrix-appservice-slack",
"The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.": "The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.", "is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.": "is a Slack bridge that supports bridging Slack channels to Matrix. Users authorize the bridge to access their Slack workspaces and from there they can pick the channels they'd like to bridge.",
"Shared Secret": "Shared Secret", "self-hosted Telegram bridge": "self-hosted Telegram bridge",
"The shared secret defined in the configuration for provisioning.": "The shared secret defined in the configuration for provisioning.", "Self-hosted Telegram bridges must have": "Self-hosted Telegram bridges must have",
"Promote Telegram Puppeting": "Promote Telegram Puppeting", "The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.": "The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.",
"If enabled, Dimension will recommend that users log in to their Telegram accounts.": "If enabled, Dimension will recommend that users log in to their Telegram accounts.", "Promote Telegram Puppeting": "Promote Telegram Puppeting",
"Promote Matrix Puppeting": "Promote Matrix Puppeting", "If enabled, Dimension will recommend that users log in to their Telegram accounts.": "If enabled, Dimension will recommend that users log in to their Telegram accounts.",
"If enabled, Dimension will recommend that users log in to their Matrix accounts.": "If enabled, Dimension will recommend that users log in to their Matrix accounts.", "Promote Matrix Puppeting": "Promote Matrix Puppeting",
"mautrix-telegram": "mautrix-telegram", "If enabled, Dimension will recommend that users log in to their Matrix accounts.": "If enabled, Dimension will recommend that users log in to their Matrix accounts.",
"is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.": "is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.", "mautrix-telegram": "mautrix-telegram",
"Enabled Features": "Enabled Features", "is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.": "is a Telegram bridge that supports bridging channels/supergroups to Matrix. This can be done through a 'relay bot' (all Matrix users are represented through a single bot in Telegram) or by making use of a user's real Telegram account (known as 'puppeting'). Currently only one Telegram bridge can be configured at a time.",
"self-hosted webhook bridge": "self-hosted webhook bridge", "Enabled Features": "Enabled Features",
"Self-hosted webhook bridges must have": "Self-hosted webhook bridges must have", "self-hosted webhook bridge": "self-hosted webhook bridge",
"The public URL for the bridge.": "The public URL for the bridge.", "Self-hosted webhook bridges must have": "Self-hosted webhook bridges must have",
"The provisioning secret defined in the configuration.": "The provisioning secret defined in the configuration.", "The public URL for the bridge.": "The public URL for the bridge.",
"matrix-appservice-webhooks": "matrix-appservice-webhooks", "The provisioning secret defined in the configuration.": "The provisioning secret defined in the configuration.",
"provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.": "provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.", "matrix-appservice-webhooks": "matrix-appservice-webhooks",
"custom bot": "custom bot", "provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.": "provides Slack-compatible webhooks for Matrix, making it easy to send updates into a room.",
"The user ID that Dimension will invite to rooms.": "The user ID that Dimension will invite to rooms.", "custom bot": "custom bot",
"A few words here will help people understand what the bot does.": "A few words here will help people understand what the bot does.", "The user ID that Dimension will invite to rooms.": "The user ID that Dimension will invite to rooms.",
"Display Name": "Display Name", "A few words here will help people understand what the bot does.": "A few words here will help people understand what the bot does.",
"This is the name Dimension will use to tell users which bot this is.": "This is the name Dimension will use to tell users which bot this is.", "Display Name": "Display Name",
"This can either be an MXC URI or a plain URL.": "This can either be an MXC URI or a plain URL.", "This is the name Dimension will use to tell users which bot this is.": "This is the name Dimension will use to tell users which bot this is.",
"This is used by Dimension to force the bot to leave the room when the user removes the bot.": "This is used by Dimension to force the bot to leave the room when the user removes the bot.", "This can either be an MXC URI or a plain URL.": "This can either be an MXC URI or a plain URL.",
"Learn more about access tokens.": "Learn more about access tokens.", "This is used by Dimension to force the bot to leave the room when the user removes the bot.": "This is used by Dimension to force the bot to leave the room when the user removes the bot.",
"Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.": "Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.", "Learn more about access tokens.": "Learn more about access tokens.",
"No custom bots.": "No custom bots.", "Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.": "Custom bots give you the ability to add your own bots to Dimension for users to add to their rooms. These bots can't have any configuration to them and must be able to accept room invites on their own. All Dimension will do when a user wants to add the bot is invite it to the room.",
"Add custom bot": "Add custom bot", "No custom bots.": "No custom bots.",
"Custom bots": "Custom bots", "Add custom bot": "Add custom bot",
"Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.": "Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.", "Custom bots": "Custom bots",
"Administrators": "Administrators", "Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.": "Parts of your configuration are displayed below. To change these values, edit your configuration and restart Dimension.",
"Widget Blacklist": "Widget Blacklist", "Administrators": "Administrators",
"Homeserver": "Homeserver", "Widget Blacklist": "Widget Blacklist",
"Federation URL": "Federation URL", "Homeserver": "Homeserver",
"Federation Hostname": "Federation Hostname", "Federation URL": "Federation URL",
"Client/Server URL": "Client/Server URL", "Federation Hostname": "Federation Hostname",
"Utility User ID": "Utility User ID", "Client/Server URL": "Client/Server URL",
"Sessions": "Sessions", "Utility User ID": "Utility User ID",
"Tokens registered": "Tokens registered", "Sessions": "Sessions",
"Logout Everyone": "Logout Everyone", "Tokens registered": "Tokens registered",
"Configuration": "Configuration", "Logout Everyone": "Logout Everyone",
"Logout confirmation": "Logout confirmation", "Configuration": "Configuration",
"Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.": "Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.", "Logout confirmation": "Logout confirmation",
"Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.": "Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.", "Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.": "Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.",
"User Prefix": "User Prefix", "Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.": "Self-hosted go-neb instances are powered by application services installed on your homeserver. The application service is responsible for creating the bots dynamically.",
"This is the prefix used for all bot users.": "This is the prefix used for all bot users.", "User Prefix": "User Prefix",
"API URL": "API URL", "This is the prefix used for all bot users.": "This is the prefix used for all bot users.",
"The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.": "The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.", "API URL": "API URL",
"New self-hosted go-neb": "New self-hosted go-neb", "The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.": "The admin/api url for go-neb. Be sure to not expose the admin API to the outside world because this endpoint is not authenticated.",
"go-neb appservice configuration": "go-neb appservice configuration", "New self-hosted go-neb": "New self-hosted go-neb",
"Copy and paste this configuration to": "Copy and paste this configuration to", "go-neb appservice configuration": "go-neb appservice configuration",
"on your homeserver and register it as an application service.": "on your homeserver and register it as an application service.", "Copy and paste this configuration to": "Copy and paste this configuration to",
"Test Configuration": "Test Configuration", "on your homeserver and register it as an application service.": "on your homeserver and register it as an application service.",
"Giphy Configuration": "Giphy Configuration", "Test Configuration": "Test Configuration",
"Api Key": "Api Key", "Giphy Configuration": "Giphy Configuration",
"The API key from": "The API key from", "Api Key": "Api Key",
"Image Size": "Image Size", "The API key from": "The API key from",
"GIFs can be large, and sometimes it is more desirable to have them downsized.": "GIFs can be large, and sometimes it is more desirable to have them downsized.", "Image Size": "Image Size",
"Use downsized images": "Use downsized images", "GIFs can be large, and sometimes it is more desirable to have them downsized.": "GIFs can be large, and sometimes it is more desirable to have them downsized.",
"Google Configuration": "Google Configuration", "Use downsized images": "Use downsized images",
"The API key for your Google Application.": "The API key for your Google Application.", "Google Configuration": "Google Configuration",
"The search engine ID": "The search engine ID", "The API key for your Google Application.": "The API key for your Google Application.",
"Guggy Configuration": "Guggy Configuration", "Search Engine ID": "Search Engine ID",
"The API key for": "The API key for", "The search engine ID": "The search engine ID",
"Imgur Configuration": "Imgur Configuration", "Guggy Configuration": "Guggy Configuration",
"Client ID": "Client ID", "The API key for": "The API key for",
"The client ID of your": "The client ID of your", "Imgur Configuration": "Imgur Configuration",
"Imgur Application": "Imgur Application", "Client ID": "Client ID",
"Client Secret": "Client Secret", "The client ID of your": "The client ID of your",
"The client secret of your": "The client secret of your", "Imgur Application": "Imgur Application",
"go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.": "go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.", "Client Secret": "Client Secret",
"is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).": "is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).", "The client secret of your": "The client secret of your",
"Enabled Bots": "Enabled Bots", "go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.": "go-neb supports many different types of bots, each of which is listed below. Here you can configure which bots this go-neb instance should use.",
"No go-neb configurations.": "No go-neb configurations.", "is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).": "is a multi-purpose bot that can provide various services, such as reaction GIFs and Github notifications. There are two options for go-neb support in Dimension: using matrix.org's or self-hosting it. Each go-neb instance can have multiple services associated with it (ie: one go-neb here can do everything).",
"Add matrix.org's go-neb": "Add matrix.org's go-neb", "Enabled Bots": "Enabled Bots",
"Add self-hosted go-neb": "Add self-hosted go-neb", "No go-neb configurations.": "No go-neb configurations.",
"go-neb configurations": "go-neb configurations", "Add matrix.org's go-neb": "Add matrix.org's go-neb",
"Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.": "Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.", "Add self-hosted go-neb": "Add self-hosted go-neb",
"Import from Telegram": "Import from Telegram", "go-neb configurations": "go-neb configurations",
"Author": "Author", "Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.": "Sticker packs provide a way to convey memes or feelings to others in a room. From here you're able to select which sticker packs users of this Dimension instance can use. If no sticker packs are enabled then the 'sticker picker' widget will be disabled.",
"License": "License", "Import from Telegram": "Import from Telegram",
"No sticker packs installed.": "No sticker packs installed.", "Author": "Author",
"Dimension": "Dimension", "License": "License",
"version": "version", "No sticker packs installed.": "No sticker packs installed.",
"The translated name of your policy": "The translated name of your policy", "Dimension": "Dimension",
"Policy text": "Policy text", "version": "version",
"This is where you put your policy's content.": "This is where you put your policy's content.", "The translated name of your policy": "The translated name of your policy",
"Create draft": "Create draft", "Policy text": "Policy text",
"Save draft": "Save draft", "This is where you put your policy's content.": "This is where you put your policy's content.",
"Publish": "Publish", "Create draft": "Create draft",
"Publish policy": "Publish policy", "Save draft": "Save draft",
"Version number": "Version number", "Publish": "Publish",
"The version number of this policy": "The version number of this policy", "Publish policy": "Publish policy",
"Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.": "Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.", "Version number": "Version number",
"Policy Name": "Policy Name", "The version number of this policy": "The version number of this policy",
"Version": "Version", "Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.": "Before users can use Dimension they must agree to the terms of service for using your instance. If you're using any matrix.org bridges, users will be required to accept the terms of service for your upstream integration managers (scalar.vector.im usually) in addition to the terms you add here.",
"No policies written.": "No policies written.", "Policy Name": "Policy Name",
"New draft policy": "New draft policy", "Version": "Version",
"Etherpad Widget Configuration": "Etherpad Widget Configuration", "No policies written.": "No policies written.",
"Default Pad URL Template": "Default Pad URL Template", "New draft policy": "New draft policy",
"$padName and $roomId will be replaced during creation to help create a unique pad URL.": "$padName and $roomId will be replaced during creation to help create a unique pad URL.", "Etherpad Widget Configuration": "Etherpad Widget Configuration",
"Jitsi Widget Configuration": "Jitsi Widget Configuration", "Default Pad URL Template": "Default Pad URL Template",
"Jitsi Domain": "Jitsi Domain", "$padName and $roomId will be replaced during creation to help create a unique pad URL.": "$padName and $roomId will be replaced during creation to help create a unique pad URL.",
"This is the domain that is used to host the conference.": "This is the domain that is used to host the conference.", "Jitsi Widget Configuration": "Jitsi Widget Configuration",
"Use this domain as the default conference domain": "Use this domain as the default conference domain", "Jitsi Domain": "Jitsi Domain",
"Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.": "Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.", "This is the domain that is used to host the conference.": "This is the domain that is used to host the conference.",
"Jitsi Script URL": "Jitsi Script URL", "Use this domain as the default conference domain": "Use this domain as the default conference domain",
"This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.": "This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.", "Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.": "Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you'll force Dimension to use your Jitsi domain at risk of having clients not respect it.",
"Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.": "Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.", "Jitsi Script URL": "Jitsi Script URL",
"Bridge to Gitter": "Bridge to Gitter", "This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.": "This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.",
"This room is bridged to on Gitter": "This room is bridged to on Gitter", "Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.": "Widgets are small webpages that can be embedded in a Matrix room. Here you can configure which widgets Dimension will offer to users.",
"on Gitter": "on Gitter", "Bridge to Github": "Bridge to Github",
"Unbridge": "Unbridge", "In order to bridge to Github, you'll need to authorize the bridge to access your organization(s). Please click the button below to do so.": "In order to bridge to Github, you'll need to authorize the bridge to access your organization(s). Please click the button below to do so.",
"Gitter Room": "Gitter Room", "Organization": "Organization",
"Add an IRC channel": "Add an IRC channel", "Repository": "Repository",
"Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.": "Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.", "Add an IRC channel": "Add an IRC channel",
"Channel Name": "Channel Name", "Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.": "Bridging a channel requires authorization from a channel operator. When entering a channel below, a bot will join the channel to ensure it exists and has operators available.",
"Next": "Next", "Channel Name": "Channel Name",
"Operator": "Operator", "Next": "Next",
"The person selected here will be asked to approve or deny the bridge request.": "The person selected here will be asked to approve or deny the bridge request.", "Operator": "Operator",
"Request Bridge": "Request Bridge", "The person selected here will be asked to approve or deny the bridge request.": "The person selected here will be asked to approve or deny the bridge request.",
"IRC Networks": "IRC Networks", "Request Bridge": "Request Bridge",
"Channel": "Channel", "IRC Networks": "IRC Networks",
"No bridged channels": "No bridged channels", "Channel": "Channel",
"Remove": "Remove", "No bridged channels": "No bridged channels",
"Bridge to Slack": "Bridge to Slack", "Remove": "Remove",
"This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.": "This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.", "Bridge to Slack": "Bridge to Slack",
"In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.": "In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.", "This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.": "This room is bridged to Slack using webhooks. Webhook bridging is legacy and doesn't support as rich bridging as the new approach. It is recommended to re-create the bridge with the new process.",
"Team": "Team", "Unbridge": "Unbridge",
"Telegram chat is already bridged": "Telegram chat is already bridged", "In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.": "In order to bridge Slack channels, you'll need to authorize the bridge to access your teams and channels. Please click the button below to do so.",
"You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?": "You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?", "Team": "Team",
"Unbridge and continue": "Unbridge and continue", "Telegram chat is already bridged": "Telegram chat is already bridged",
"No, don't bridge": "No, don't bridge", "You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?": "You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?",
"That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.": "That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.", "Unbridge and continue": "Unbridge and continue",
"Bridge to Telegram": "Bridge to Telegram", "No, don't bridge": "No, don't bridge",
"This room is bridged to on Telegram": "This room is bridged to on Telegram", "That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.": "That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.",
"on Telegram": "on Telegram", "Bridge to Telegram": "Bridge to Telegram",
"You do not have the necessary permissions in this room to unbridge the channel.": "You do not have the necessary permissions in this room to unbridge the channel.", "This room is bridged to on Telegram": "This room is bridged to on Telegram",
"After inviting": "After inviting", "on Telegram": "on Telegram",
"to your Telegram chat, run the command": "to your Telegram chat, run the command", "You do not have the necessary permissions in this room to unbridge the channel.": "You do not have the necessary permissions in this room to unbridge the channel.",
"in the Telegram room to get the chat ID.": "in the Telegram room to get the chat ID.", "After inviting": "After inviting",
"Add a new webhook": "Add a new webhook", "to your Telegram chat, run the command": "to your Telegram chat, run the command",
"Webhook Name": "Webhook Name", "in the Telegram room to get the chat ID.": "in the Telegram room to get the chat ID.",
"Create": "Create", "Add a new webhook": "Add a new webhook",
"Type": "Type", "Webhook Name": "Webhook Name",
"No webhooks": "No webhooks", "Create": "Create",
"No name": "No name", "Type": "Type",
"Delete": "Delete", "No webhooks": "No webhooks",
"Feeds": "Feeds", "No name": "No name",
"Added by": "Added by", "Delete": "Delete",
"Add": "Add", "Feeds": "Feeds",
".travis.yml configuration and template information": ".travis.yml configuration and template information", "Added by": "Added by",
"The following section needs to be added to your": "The following section needs to be added to your", "Add": "Add",
"file in your repositories:": "file in your repositories:", ".travis.yml configuration and template information": ".travis.yml configuration and template information",
"The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.": "The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.", "The following section needs to be added to your": "The following section needs to be added to your",
"The repository identifier": "The repository identifier", "file in your repositories:": "file in your repositories:",
"The repository name": "The repository name", "The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.": "The following variables can be used in your template. This template is used to post a message to theroom when your webhook is activated.",
"The build number": "The build number", "The repository identifier": "The repository identifier",
"The build ID": "The build ID", "The repository name": "The repository name",
"The branch name": "The branch name", "The build number": "The build number",
"A short version of the commit SHA": "A short version of the commit SHA", "The build ID": "The build ID",
"The first line of the commit message": "The first line of the commit message", "The branch name": "The branch name",
"The full commit message": "The full commit message", "A short version of the commit SHA": "A short version of the commit SHA",
"The author of the commit": "The author of the commit", "The first line of the commit message": "The first line of the commit message",
"The result of the build": "The result of the build", "The full commit message": "The full commit message",
"The message from Travis CI about the build": "The message from Travis CI about the build", "The author of the commit": "The author of the commit",
"The total duration of all builds in the matrix": "The total duration of all builds in the matrix", "The result of the build": "The result of the build",
"The time it took to run the build": "The time it took to run the build", "The message from Travis CI about the build": "The message from Travis CI about the build",
"A URL to see the changes which triggered the build": "A URL to see the changes which triggered the build", "The total duration of all builds in the matrix": "The total duration of all builds in the matrix",
"A URL to see the build information": "A URL to see the build information", "The time it took to run the build": "The time it took to run the build",
"Repositories": "Repositories", "A URL to see the changes which triggered the build": "A URL to see the changes which triggered the build",
"Repository": "Repository", "A URL to see the build information": "A URL to see the build information",
"Template": "Template", "Repositories": "Repositories",
"Sticker packs are not enabled on this Dimension instance.": "Sticker packs are not enabled on this Dimension instance.", "Template": "Template",
"Start a conversation with": "Start a conversation with", "Sticker packs are not enabled on this Dimension instance.": "Sticker packs are not enabled on this Dimension instance.",
"to create your own stickerpack.": "to create your own stickerpack.", "Start a conversation with": "Start a conversation with",
"Add stickerpack": "Add stickerpack", "to create your own stickerpack.": "to create your own stickerpack.",
"Created by": "Created by", "Add stickerpack": "Add stickerpack",
"under": "under", "Created by": "Created by",
"BigBlueButton Meeting URL": "BigBlueButton Meeting URL", "under": "under",
"Add Widget": "Add Widget", "BigBlueButton Meeting URL": "BigBlueButton Meeting URL",
"Save Widget": "Save Widget", "Add Widget": "Add Widget",
"Remove Widget": "Remove Widget", "Save Widget": "Save Widget",
"Widget Name": "Widget Name", "Remove Widget": "Remove Widget",
"Widget URL": "Widget URL", "Widget Name": "Widget Name",
"Pad Name": "Pad Name", "Widget URL": "Widget URL",
"Pad URL": "Pad URL", "Pad Name": "Pad Name",
"Shared Calendar ID": "Shared Calendar ID", "Pad URL": "Pad URL",
"Document URL": "Document URL", "Shared Calendar ID": "Shared Calendar ID",
"Grafana URL": "Grafana URL", "Document URL": "Document URL",
"To get a URL, go to Grafana and click 'share' on a graph.": "To get a URL, go to Grafana and click 'share' on a graph.", "Grafana URL": "Grafana URL",
"Conference URL": "Conference URL", "To get a URL, go to Grafana and click 'share' on a graph.": "To get a URL, go to Grafana and click 'share' on a graph.",
" Spotify URI": " Spotify URI", "Conference URL": "Conference URL",
"Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.": "Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.", " Spotify URI": " Spotify URI",
"Trading Pair": "Trading Pair", "Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.": "Click 'share' from your favourite playlist, artist, track, or album and paste the Spotify URI here.",
"Interval": "Interval", "Trading Pair": "Trading Pair",
"Whiteboard Name": "Whiteboard Name", "Interval": "Interval",
"Whiteboard URL": "Whiteboard URL", "Whiteboard Name": "Whiteboard Name",
"Video URL": "Video URL", "Whiteboard URL": "Whiteboard URL",
"An open source integration manager for Matrix": "An open source integration manager for Matrix", "Video URL": "Video URL",
"Self-host your favourite bots, bridges, and widgets.": "Self-host your favourite bots, bridges, and widgets.", "An open source integration manager for Matrix": "An open source integration manager for Matrix",
"source": "source", "Self-host your favourite bots, bridges, and widgets.": "Self-host your favourite bots, bridges, and widgets.",
"Try it out or": "Try it out or", "source": "source",
"run your own": "run your own", "Try it out or": "Try it out or",
"Visit": "Visit", "run your own": "run your own",
"and log in with your Matrix account or point your Element": "and log in with your Matrix account or point your Element", "Visit": "Visit",
"at our servers:": "at our servers:", "and log in with your Matrix account or point your Element": "and log in with your Matrix account or point your Element",
"Add utility for everyone in your room by embedding an application.": "Add utility for everyone in your room by embedding an application.", "at our servers:": "at our servers:",
"Notes": "Notes", "Add utility for everyone in your room by embedding an application.": "Add utility for everyone in your room by embedding an application.",
"Google Calendar": "Google Calendar", "Notes": "Notes",
"Custom Widget": "Custom Widget", "Google Calendar": "Google Calendar",
"Bots bring entertainment or productivity to the room. They're here to help at your command.": "Bots bring entertainment or productivity to the room. They're here to help at your command.", "Custom Widget": "Custom Widget",
"Guggy": "Guggy", "Bots bring entertainment or productivity to the room. They're here to help at your command.": "Bots bring entertainment or productivity to the room. They're here to help at your command.",
"Giphy": "Giphy", "Guggy": "Guggy",
"Imgur": "Imgur", "Giphy": "Giphy",
"Google Image Search": "Google Image Search", "Imgur": "Imgur",
"Wikipedia": "Wikipedia", "Google Image Search": "Google Image Search",
"Travis CI": "Travis CI", "Wikipedia": "Wikipedia",
"RSS Notifications": "RSS Notifications", "Travis CI": "Travis CI",
"Echo": "Echo", "RSS Notifications": "RSS Notifications",
"Bring the outside world into your room with bridges.": "Bring the outside world into your room with bridges.", "Echo": "Echo",
"Stickers": "Stickers", "Bring the outside world into your room with bridges.": "Bring the outside world into your room with bridges.",
"Have some fun and post a sticker.": "Have some fun and post a sticker.", "Stickers": "Stickers",
"Huskies": "Huskies", "Have some fun and post a sticker.": "Have some fun and post a sticker.",
"Cats": "Cats", "Huskies": "Huskies",
"Cat Faces": "Cat Faces", "Cats": "Cats",
"Loading Artist": "Loading Artist", "Cat Faces": "Cat Faces",
"source on GitHub": "source on GitHub", "Loading Artist": "Loading Artist",
"Welcome to Dimension!": "Welcome to Dimension!", "source on GitHub": "source on GitHub",
"Join": "Join", "Welcome to Dimension!": "Welcome to Dimension!",
"for news and updates. Don't forget to star the repository on": "for news and updates. Don't forget to star the repository on", "Join": "Join",
"Here's the configuration options you'll need to update in your Element": "Here's the configuration options you'll need to update in your Element", "for news and updates. Don't forget to star the repository on": "for news and updates. Don't forget to star the repository on",
"Configuring integrations": "Configuring integrations", "Here's the configuration options you'll need to update in your Element": "Here's the configuration options you'll need to update in your Element",
"If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon": "If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon", "The location of": "The location of",
"in the top right is where you can configure your bots, bridges, and widgets.": "in the top right is where you can configure your bots, bridges, and widgets.", "differs depending on whether the": "differs depending on whether the",
"Could not connect to integrations server error": "Could not connect to integrations server error", "or": "or",
"When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in": "When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in", "version of Element is used.": "version of Element is used.",
"on Matrix, here's a few things to check:": "on Matrix, here's a few things to check:", "Configuring integrations": "Configuring integrations",
"Verify the homeserver configuration in Dimension.": "Verify the homeserver configuration in Dimension.", "If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon": "If everything is set up correctly, you'll be able to access the admin area of Dimension by clicking the 3x3 grid in the top right of any room in Element. The gear icon",
"The name, client/server URL, and access token all need to be valid and directed at your homeserver.": "The name, client/server URL, and access token all need to be valid and directed at your homeserver.", "in the top right is where you can configure your bots, bridges, and widgets.": "in the top right is where you can configure your bots, bridges, and widgets.",
"Verify federation is enabled on your homeserver.": "Verify federation is enabled on your homeserver.", "Could not connect to integrations server error": "Could not connect to integrations server error",
"Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.": "Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.", "When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in": "When Element cannot reach Dimension or Dimension is unable to reach your homeserver an error saying 'Could not contact integrations server' shows up in every room. Before visiting us in",
"Verify that federation is working on your homeserver.": "Verify that federation is working on your homeserver.", "on Matrix, here's a few things to check:": "on Matrix, here's a few things to check:",
"Using tools like the": "Using tools like the", "Verify the homeserver configuration in Dimension.": "Verify the homeserver configuration in Dimension.",
"federation tester": "federation tester", "The name, client/server URL, and access token all need to be valid and directed at your homeserver.": "The name, client/server URL, and access token all need to be valid and directed at your homeserver.",
", make sure that federation is working on your homeserver.": ", make sure that federation is working on your homeserver.", "Verify federation is enabled on your homeserver.": "Verify federation is enabled on your homeserver.",
"Looking for your sticker packs?": "Looking for your sticker packs?", "Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.": "Even in a private, or non-federated, environment federation needs to be enabled so Dimension can work correctly. Dimension should still work okay if federation on your homeserver is bound to a private interface instead of being public - just be sure to set the federation URL in your configuration.",
"Click here": "Click here", "Verify that federation is working on your homeserver.": "Verify that federation is working on your homeserver.",
"This room is encrypted": "This room is encrypted", "Using tools like the": "Using tools like the",
"Integrations are not encrypted!": "Integrations are not encrypted!", "federation tester": "federation tester",
"This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.": "This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.", ", make sure that federation is working on your homeserver.": ", make sure that federation is working on your homeserver.",
"There are currently no integrations which support encrypted rooms. Sorry about that!": "There are currently no integrations which support encrypted rooms. Sorry about that!", "Looking for your sticker packs?": "Looking for your sticker packs?",
"No integrations available": "No integrations available", "Click here": "Click here",
"This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.": "This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.", "This room is encrypted": "This room is encrypted",
"BigBlueButton Conference": "BigBlueButton Conference", "Integrations are not encrypted!": "Integrations are not encrypted!",
"Join Conference": "Join Conference", "This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.": "This means that some information about yourself and the room may be leaked to the bot, bridge, or widget. This information includes the room ID, your display name, your username, your avatar, information about Element, and other similar details. Add integrations with caution.",
"Sorry, this content cannot be embedded": "Sorry, this content cannot be embedded", "There are currently no integrations which support encrypted rooms. Sorry about that!": "There are currently no integrations which support encrypted rooms. Sorry about that!",
"Start camera:": "Start camera:", "No integrations available": "No integrations available",
"You": "You", "This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.": "This room does not have any compatible integrations. Please contact the server owner if you're seeing this message.",
"Integrations": "Integrations", "BigBlueButton Conference": "BigBlueButton Conference",
"Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.": "Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.", "Join Conference": "Join Conference",
"Check connection": "Check connection", "Sorry, this content cannot be embedded": "Sorry, this content cannot be embedded",
"Click to start OpenID auth": "Click to start OpenID auth", "Start camera:": "Start camera:",
"User ID:": "User ID:", "You": "You",
"You have blocked this widget from receiving credentials.": "You have blocked this widget from receiving credentials.", "Integrations": "Integrations",
"An error has occurred - see logs for details": "An error has occurred - see logs for details", "Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.": "Your client is too old to use this widget. Try upgrading your client to the latest available version, or contact the author to try and diagnose the problem. Your client needs to support OpenID information exchange.",
"There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.": "There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.", "Check connection": "Check connection",
"You have no sticker packs.": "You have no sticker packs.", "Click to start OpenID auth": "Click to start OpenID auth",
"Add some stickers": "Add some stickers", "User ID:": "User ID:",
"Failed to load bridges": "Failed to load bridges", "You have blocked this widget from receiving credentials.": "You have blocked this widget from receiving credentials.",
"Error loading bridges": "Error loading bridges", "An error has occurred - see logs for details": "An error has occurred - see logs for details",
"matrix.org's Gitter bridge added": "matrix.org's Gitter bridge added", "There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.": "There was a problem authenticating your use of this sticker picker. Please make sure you're using a client that has Dimension enabled and correctly set up.",
"Error adding matrix.org's Gitter Bridge": "Error adding matrix.org's Gitter Bridge", "You have no sticker packs.": "You have no sticker packs.",
"Error creating matrix.org's Gitter Bridge": "Error creating matrix.org's Gitter Bridge", "Add some stickers": "Add some stickers",
"Failed to get an update Gitter bridge list": "Failed to get an update Gitter bridge list", "Failed to load bridges": "Failed to load bridges",
"Gitter bridge added": "Gitter bridge added", "Error loading bridges": "Error loading bridges",
"Failed to create Gitter bridge": "Failed to create Gitter bridge", "Failed to get an updated Github bridge list": "Failed to get an updated Github bridge list",
"Gitter bridge updated": "Gitter bridge updated", "Github bridge added": "Github bridge added",
"Failed to update Gitter bridge": "Failed to update Gitter bridge", "Failed to create Github bridge": "Failed to create Github bridge",
"IRC Bridge added": "IRC Bridge added", "Github bridge updated": "Github bridge updated",
"Failed to create IRC bridge": "Failed to create IRC bridge", "Failed to update Github bridge": "Failed to update Github bridge",
"Click the pencil icon to enable networks.": "Click the pencil icon to enable networks.", "IRC Bridge added": "IRC Bridge added",
"matrix.org's IRC bridge added": "matrix.org's IRC bridge added", "Failed to create IRC bridge": "Failed to create IRC bridge",
"Error adding matrix.org's IRC Bridge": "Error adding matrix.org's IRC Bridge", "Click the pencil icon to enable networks.": "Click the pencil icon to enable networks.",
"Error creating matrix.org's IRC Bridge": "Error creating matrix.org's IRC Bridge", "matrix.org's IRC bridge added": "matrix.org's IRC bridge added",
"Failed to get an update IRC bridge list": "Failed to get an update IRC bridge list", "Error adding matrix.org's IRC Bridge": "Error adding matrix.org's IRC Bridge",
"disabled": "disabled", "Error creating matrix.org's IRC Bridge": "Error creating matrix.org's IRC Bridge",
"Failed to update network": "Failed to update network", "Failed to get an update IRC bridge list": "Failed to get an update IRC bridge list",
"Slack bridge added": "Slack bridge added", "disabled": "disabled",
"Failed to create Slack bridge": "Failed to create Slack bridge", "Failed to update network": "Failed to update network",
"Slack bridge updated": "Slack bridge updated", "Slack bridge added": "Slack bridge added",
"Failed to update Slack bridge": "Failed to update Slack bridge", "Failed to create Slack bridge": "Failed to create Slack bridge",
"matrix.org's Slack bridge added": "matrix.org's Slack bridge added", "Slack bridge updated": "Slack bridge updated",
"Error adding matrix.org's Slack Bridge": "Error adding matrix.org's Slack Bridge", "Failed to update Slack bridge": "Failed to update Slack bridge",
"Error creating matrix.org's Slack Bridge": "Error creating matrix.org's Slack Bridge", "matrix.org's Slack bridge added": "matrix.org's Slack bridge added",
"Failed to get an update Slack bridge list": "Failed to get an update Slack bridge list", "Error adding matrix.org's Slack Bridge": "Error adding matrix.org's Slack Bridge",
"Telegram bridge added": "Telegram bridge added", "Error creating matrix.org's Slack Bridge": "Error creating matrix.org's Slack Bridge",
"Failed to create Telegram bridge": "Failed to create Telegram bridge", "Failed to get an update Slack bridge list": "Failed to get an update Slack bridge list",
"Telegram bridge updated": "Telegram bridge updated", "Telegram bridge added": "Telegram bridge added",
"Failed to update Telegram bridge": "Failed to update Telegram bridge", "Failed to create Telegram bridge": "Failed to create Telegram bridge",
"Failed to get an update Telegram bridge list": "Failed to get an update Telegram bridge list", "Telegram bridge updated": "Telegram bridge updated",
"Webhook bridge added": "Webhook bridge added", "Failed to update Telegram bridge": "Failed to update Telegram bridge",
"Failed to create Webhook bridge": "Failed to create Webhook bridge", "Failed to get an update Telegram bridge list": "Failed to get an update Telegram bridge list",
"Webhook bridge updated": "Webhook bridge updated", "Webhook bridge added": "Webhook bridge added",
"Failed to update Webhook bridge": "Failed to update Webhook bridge", "Failed to create Webhook bridge": "Failed to create Webhook bridge",
"Failed to get an update Webhooks bridge list": "Failed to get an update Webhooks bridge list", "Webhook bridge updated": "Webhook bridge updated",
"Please enter a name for the bot": "Please enter a name for the bot", "Failed to update Webhook bridge": "Failed to update Webhook bridge",
"Please enter an avatar URL for the bot": "Please enter an avatar URL for the bot", "Failed to get an update Webhooks bridge list": "Failed to get an update Webhooks bridge list",
"Please enter a user ID for the bot": "Please enter a user ID for the bot", "Please enter a name for the bot": "Please enter a name for the bot",
"Please enter a description for the bot": "Please enter a description for the bot", "Please enter an avatar URL for the bot": "Please enter an avatar URL for the bot",
"Please enter an access token for the bot": "Please enter an access token for the bot", "Please enter a user ID for the bot": "Please enter a user ID for the bot",
"Bot updated": "Bot updated", "Please enter a description for the bot": "Please enter a description for the bot",
"Error updating bot": "Error updating bot", "Please enter an access token for the bot": "Please enter an access token for the bot",
"Error loading go-neb configuration": "Error loading go-neb configuration", "Bot updated": "Bot updated",
"Failed to get an updated bot list": "Failed to get an updated bot list", "Error updating bot": "Error updating bot",
"Everyone has been logged out": "Everyone has been logged out", "Error loading go-neb configuration": "Error loading go-neb configuration",
"Error logging everyone out": "Error logging everyone out", "Failed to get an updated bot list": "Failed to get an updated bot list",
"New go-neb created": "New go-neb created", "Everyone has been logged out": "Everyone has been logged out",
"Error creating appservice": "Error creating appservice", "Error logging everyone out": "Error logging everyone out",
"Could not load appservice configuration": "Could not load appservice configuration", "New go-neb created": "New go-neb created",
"The appservice appears to be correctly set up": "The appservice appears to be correctly set up", "Error creating appservice": "Error creating appservice",
"The appservice is not correctly set up": "The appservice is not correctly set up", "Could not load appservice configuration": "Could not load appservice configuration",
"Error loading configuration": "Error loading configuration", "The appservice appears to be correctly set up": "The appservice appears to be correctly set up",
"Configuration updated": "Configuration updated", "The appservice is not correctly set up": "The appservice is not correctly set up",
"Error updating integration": "Error updating integration", "Error loading configuration": "Error loading configuration",
"Integration updated": "Integration updated", "Configuration updated": "Configuration updated",
"Failed to configure the integration": "Failed to configure the integration", "Error updating integration": "Error updating integration",
"Manual troubleshooting may be requred": "Manual troubleshooting may be requred", "Integration updated": "Integration updated",
"Could not get go-neb configuration": "Could not get go-neb configuration", "Failed to configure the integration": "Failed to configure the integration",
"matrix.org's go-neb added": "matrix.org's go-neb added", "Manual troubleshooting may be requred": "Manual troubleshooting may be requred",
"Click the pencil icon to enable the bots.": "Click the pencil icon to enable the bots.", "Could not get go-neb configuration": "Could not get go-neb configuration",
"Error adding matrix.org's go-neb": "Error adding matrix.org's go-neb", "matrix.org's go-neb added": "matrix.org's go-neb added",
"Error creating matrix.org go-neb": "Error creating matrix.org go-neb", "Click the pencil icon to enable the bots.": "Click the pencil icon to enable the bots.",
"Failed to load sticker packs": "Failed to load sticker packs", "Error adding matrix.org's go-neb": "Error adding matrix.org's go-neb",
"Sticker pack updated": "Sticker pack updated", "Error creating matrix.org go-neb": "Error creating matrix.org go-neb",
"Error updating sticker pack": "Error updating sticker pack", "Failed to load sticker packs": "Failed to load sticker packs",
"Telegram sticker pack imported": "Telegram sticker pack imported", "Sticker pack updated": "Sticker pack updated",
"Error importing sticker pack": "Error importing sticker pack", "Error updating sticker pack": "Error updating sticker pack",
"Failed to load policy": "Failed to load policy", "Telegram sticker pack imported": "Telegram sticker pack imported",
"Failed to load policies": "Failed to load policies", "Error importing sticker pack": "Error importing sticker pack",
"Policy published": "Policy published", "Failed to load policy": "Failed to load policy",
"Error publishing policy": "Error publishing policy", "Failed to load policies": "Failed to load policies",
"Please enter a name for all policies": "Please enter a name for all policies", "Policy published": "Policy published",
"Please enter text for all policies": "Please enter text for all policies", "Error publishing policy": "Error publishing policy",
"Draft saved": "Draft saved", "Please enter a name for all policies": "Please enter a name for all policies",
"Error saving policy": "Error saving policy", "Please enter text for all policies": "Please enter text for all policies",
"Draft created": "Draft created", "Draft saved": "Draft saved",
"Error creating document": "Error creating document", "Error saving policy": "Error saving policy",
"Please enter a version number": "Please enter a version number", "Draft created": "Draft created",
"Widget updated": "Widget updated", "Error creating document": "Error creating document",
"Error updating widget": "Error updating widget", "Please enter a version number": "Please enter a version number",
"Failed to load widgets": "Failed to load widgets", "Widget updated": "Widget updated",
"Error opening configuration page": "Error opening configuration page", "Error updating widget": "Error updating widget",
"Failed to load configuration": "Failed to load configuration", "Failed to load widgets": "Failed to load widgets",
"Error updating configuration": "Error updating configuration", "Error opening configuration page": "Error opening configuration page",
"Error inviting bridge": "Error inviting bridge", "Failed to load configuration": "Failed to load configuration",
"Bridge requested": "Bridge requested", "Error updating configuration": "Error updating configuration",
"Error requesting bridge": "Error requesting bridge", "Error inviting bridge": "Error inviting bridge",
"Bridge removed": "Bridge removed", "Bridge requested": "Bridge requested",
"Error removing bridge": "Error removing bridge", "Error requesting bridge": "Error requesting bridge",
"Please enter a channel name": "Please enter a channel name", "Bridge removed": "Bridge removed",
"Error loading channel operators": "Error loading channel operators", "Error removing bridge": "Error removing bridge",
"Failed to make the bridge an administrator": "Failed to make the bridge an administrator", "Please enter a channel name": "Please enter a channel name",
"Please ensure you are an 'Admin' for the room": "Please ensure you are an 'Admin' for the room", "Error loading channel operators": "Error loading channel operators",
"Link requested!": "Link requested!", "Failed to make the bridge an administrator": "Failed to make the bridge an administrator",
"The operator selected will have to approve the bridge for it to work": "The operator selected will have to approve the bridge for it to work", "Please ensure you are an 'Admin' for the room": "Please ensure you are an 'Admin' for the room",
"Failed to request a link": "Failed to request a link", "Link requested!": "Link requested!",
"Link removed": "Link removed", "The operator selected will have to approve the bridge for it to work": "The operator selected will have to approve the bridge for it to work",
"Failed to remove link": "Failed to remove link", "Failed to request a link": "Failed to request a link",
"Error getting Slack authorization information": "Error getting Slack authorization information", "Link removed": "Link removed",
"Error getting teams": "Error getting teams", "Failed to remove link": "Failed to remove link",
"Error getting channels for team": "Error getting channels for team", "Error getting Slack authorization information": "Error getting Slack authorization information",
"Bridge updated": "Bridge updated", "Error getting teams": "Error getting teams",
"Webhook created": "Webhook created", "Error getting channels for team": "Error getting channels for team",
"Error creating webhook": "Error creating webhook", "Bridge updated": "Bridge updated",
"Webhook deleted": "Webhook deleted", "Webhook created": "Webhook created",
"Error deleting webhook": "Error deleting webhook", "Error creating webhook": "Error creating webhook",
"Please enter a feed URL": "Please enter a feed URL", "Webhook deleted": "Webhook deleted",
"Please enter a repository": "Please enter a repository", "Error deleting webhook": "Error deleting webhook",
"was invited to the room": "was invited to the room", "Please enter a feed URL": "Please enter a feed URL",
"was removed from the room": "was removed from the room", "Please enter a repository": "Please enter a repository",
"Could not update integration status": "Could not update integration status", "was invited to the room": "was invited to the room",
"Stickerpack added": "Stickerpack added", "was removed from the room": "was removed from the room",
"Error adding stickerpack": "Error adding stickerpack", "Could not update integration status": "Could not update integration status",
"Stickers updated": "Stickers updated", "Stickerpack added": "Stickerpack added",
"Error updating stickers": "Error updating stickers", "Error adding stickerpack": "Error adding stickerpack",
"Please enter a URL for the widget": "Please enter a URL for the widget", "Stickers updated": "Stickers updated",
"Widget added!": "Widget added!", "Error updating stickers": "Error updating stickers",
"Widget updated!": "Widget updated!", "Please enter a URL for the widget": "Please enter a URL for the widget",
"Widget deleted!": "Widget deleted!", "Widget added!": "Widget added!",
"Please enter a video URL": "Please enter a video URL", "Widget updated!": "Widget updated!",
"Please enter a YouTube, Vimeo, or DailyMotion video URL": "Please enter a YouTube, Vimeo, or DailyMotion video URL", "Widget deleted!": "Widget deleted!",
"Unable to load Dimension - missing room ID or token.": "Unable to load Dimension - missing room ID or token.", "Please enter a video URL": "Please enter a video URL",
"Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!": "Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!", "Please enter a YouTube, Vimeo, or DailyMotion video URL": "Please enter a YouTube, Vimeo, or DailyMotion video URL",
"Unable to communicate with Dimension due to an unknown error.": "Unable to communicate with Dimension due to an unknown error.", "Unable to load Dimension - missing room ID or token.": "Unable to load Dimension - missing room ID or token.",
"You do not appear to have permission to modify widgets in this room": "You do not appear to have permission to modify widgets in this room", "Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!": "Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!",
"Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.": "Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.", "Unable to communicate with Dimension due to an unknown error.": "Unable to communicate with Dimension due to an unknown error.",
"This integration is offline or unavailable": "This integration is offline or unavailable", "You do not appear to have permission to modify widgets in this room": "You do not appear to have permission to modify widgets in this room",
"Could not communicate with Element": "Could not communicate with Element", "Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.": "Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.",
"The room must be": "The room must be", "This integration is offline or unavailable": "This integration is offline or unavailable",
"to use this integration": "to use this integration", "Could not communicate with Element": "Could not communicate with Element",
"You cannot modify widgets in this room": "You cannot modify widgets in this room", "You cannot modify widgets in this room": "You cannot modify widgets in this room",
"Error communicating with Element": "Error communicating with Element", "Error communicating with Element": "Error communicating with Element",
"Expected to not be able to send specific event types": "Expected to not be able to send specific event types", "Expected to not be able to send specific event types": "Expected to not be able to send specific event types",
"Expected to be able to send specific event types": "Expected to be able to send specific event types", "Expected to be able to send specific event types": "Expected to be able to send specific event types",
"Requirement": "Requirement", "Requirement": "Requirement",
"not found": "not found", "not found": "not found",
"Failed to take screenshot: iframe not supported": "Failed to take screenshot: iframe not supported", "Failed to take screenshot: iframe not supported": "Failed to take screenshot: iframe not supported",
"Failed to take screenshot": "Failed to take screenshot", "Failed to take screenshot": "Failed to take screenshot",
"Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.": "Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.", "Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.": "Click the button to test your connection. This may cause your client to ask if it is okay to share your identity with the widget - this is required to test your connection to your homeserver.",
"Please accept the prompt to verify your identity.": "Please accept the prompt to verify your identity.", "Please accept the prompt to verify your identity.": "Please accept the prompt to verify your identity.",
"You have blocked this widget from verifying your identity.": "You have blocked this widget from verifying your identity.", "You have blocked this widget from verifying your identity.": "You have blocked this widget from verifying your identity.",
"Checking connectivity to integration manager...": "Checking connectivity to integration manager...", "Checking connectivity to integration manager...": "Checking connectivity to integration manager...",
"Checking connectivity to homeserver...": "Checking connectivity to homeserver...", "Checking connectivity to homeserver...": "Checking connectivity to homeserver...",
"Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.": "Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.", "Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.": "Error checking if the integration manager is alive. This usually means that the manager which served this widget has gone offline.",
"You're all set! Click the button below to re-run the test.": "You're all set! Click the button below to re-run the test.", "You're all set! Click the button below to re-run the test.": "You're all set! Click the button below to re-run the test.",
"Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.": "Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.", "Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.": "Error contacting homeserver. This usually means your federation setup is incorrect, or your homeserver is offline. Consult your homeserver's documentation for how to set up federation.",
"Checking client version...": "Checking client version...", "Checking client version...": "Checking client version...",
"Your client is too old to use this widget, sorry": "Your client is too old to use this widget, sorry", "Your client is too old to use this widget, sorry": "Your client is too old to use this widget, sorry",
"Please accept the prompt to verify your identity": "Please accept the prompt to verify your identity", "Please accept the prompt to verify your identity": "Please accept the prompt to verify your identity",
"Error loading policy": "Error loading policy", "Error loading policy": "Error loading policy"
"The location of": "The location of", }
"differs depending on whether the": "differs depending on whether the",
"or": "or",
"version of Element is used.": "version of Element is used."
}