Commit b8d82df9 by Patrick O'Carroll Committed by Torkel Ödegaard

added no-angle-bracket-type-assertion rule and updatet files to follow rule (#13115)

parent 7837ee44
......@@ -84,7 +84,7 @@ function link(scope, elem, attrs) {
// disable depreacation warning
codeEditor.$blockScrolling = Infinity;
// Padding hacks
(<any>codeEditor.renderer).setScrollMargin(15, 15);
(codeEditor.renderer as any).setScrollMargin(15, 15);
codeEditor.renderer.setPadding(10);
setThemeMode();
......@@ -152,7 +152,7 @@ function link(scope, elem, attrs) {
if (scope.getCompleter()) {
// make copy of array as ace seems to share completers array between instances
const anyEditor = <any>codeEditor;
const anyEditor = codeEditor as any;
anyEditor.completers = anyEditor.completers.slice();
anyEditor.completers.push(scope.getCompleter());
}
......
......@@ -51,7 +51,7 @@ export class Settings {
}
}
const bootData = (<any>window).grafanaBootData || { settings: {} };
const bootData = (window as any).grafanaBootData || { settings: {} };
const options = bootData.settings;
options.bootData = bootData;
......
......@@ -60,7 +60,7 @@ export class InspectCtrl {
if (keyValue[1].length > 0) {
result.push({
key: keyValue[0],
value: (<any>window).unescape(keyValue[1]),
value: (window as any).unescape(keyValue[1]),
});
}
}
......
let templates = (<any>require).context('../', true, /\.html$/);
let templates = (require as any).context('../', true, /\.html$/);
templates.keys().forEach(function(key) {
templates(key);
});
......@@ -12,13 +12,13 @@ export class Analytics {
dataType: 'script',
cache: true,
});
const ga = ((<any>window).ga =
(<any>window).ga ||
const ga = ((window as any).ga =
(window as any).ga ||
function() {
(ga.q = ga.q || []).push(arguments);
});
ga.l = +new Date();
ga('create', (<any>config).googleAnalyticsId, 'auto');
ga('create', (config as any).googleAnalyticsId, 'auto');
ga('set', 'anonymizeIp', true);
return ga;
}
......@@ -26,7 +26,7 @@ export class Analytics {
init() {
this.$rootScope.$on('$viewContentLoaded', () => {
const track = { page: this.$location.url() };
const ga = (<any>window).ga || this.gaInit();
const ga = (window as any).ga || this.gaInit();
ga('set', track);
ga('send', 'pageview');
});
......@@ -35,7 +35,7 @@ export class Analytics {
/** @ngInject */
function startAnalytics(googleAnalyticsSrv) {
if ((<any>config).googleAnalyticsId) {
if ((config as any).googleAnalyticsId) {
googleAnalyticsSrv.init();
}
}
......
......@@ -562,5 +562,5 @@ function createCtrlWithStubs(searchResponse: any, tags?: any) {
},
};
return new ManageDashboardsCtrl({}, { getNav: () => {} }, <SearchSrv>searchSrvStub, { isEditor: true });
return new ManageDashboardsCtrl({}, { getNav: () => {} }, searchSrvStub as SearchSrv, { isEditor: true });
}
......@@ -12,7 +12,7 @@ describe('SearchCtrl', () => {
search: (options: any) => {},
getDashboardTags: () => {},
};
const ctrl = new SearchCtrl({ $on: () => {} }, {}, {}, <SearchSrv>searchSrvStub);
const ctrl = new SearchCtrl({ $on: () => {} }, {}, {}, searchSrvStub as SearchSrv);
describe('Given an empty result', () => {
beforeEach(() => {
......
......@@ -94,11 +94,11 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv,
const utcOffset = '&tz=UTC' + encodeURIComponent(moment().format('Z'));
// Older browser does not the internationalization API
if (!(<any>window).Intl) {
if (!(window as any).Intl) {
return utcOffset;
}
const dateFormat = (<any>window).Intl.DateTimeFormat();
const dateFormat = (window as any).Intl.DateTimeFormat();
if (!dateFormat.resolvedOptions) {
return utcOffset;
}
......
......@@ -4,7 +4,7 @@ import config from 'app/core/config';
import { LinkSrv } from 'app/features/panellinks/link_srv';
describe('ShareModalCtrl', () => {
const ctx = <any>{
const ctx = {
timeSrv: {
timeRange: () => {
return { from: new Date(1000), to: new Date(2000) };
......@@ -26,9 +26,9 @@ describe('ShareModalCtrl', () => {
templateSrv: {
fillVariableValuesForUrl: () => {},
},
};
} as any;
(<any>window).Intl.DateTimeFormat = () => {
(window as any).Intl.DateTimeFormat = () => {
return {
resolvedOptions: () => {
return { timeZone: 'UTC' };
......
......@@ -4,7 +4,7 @@ import moment from 'moment';
import $q from 'q';
describe('VariableSrv', function(this: any) {
const ctx = <any>{
const ctx = {
datasourceSrv: {},
timeSrv: {
timeRange: () => {},
......@@ -29,7 +29,7 @@ describe('VariableSrv', function(this: any) {
$location: {
search: () => {},
},
};
} as any;
function describeUpdateVariable(desc, fn) {
describe(desc, () => {
......
......@@ -17,12 +17,12 @@ describe('VariableSrv init', function(this: any) {
}),
};
const $injector = <any>{};
const $injector = {} as any;
const $rootscope = {
$on: () => {},
};
let ctx = <any>{};
let ctx = {} as any;
function describeInitScenario(desc, fn) {
describe(desc, () => {
......
......@@ -25,10 +25,10 @@ describe('CloudWatchDatasource', function() {
},
};
const backendSrv = {};
const ctx = <any>{
const ctx = {
backendSrv,
templateSrv,
};
} as any;
beforeEach(() => {
ctx.ds = new CloudWatchDatasource(instanceSettings, {}, backendSrv, templateSrv, timeSrv);
......
......@@ -33,10 +33,10 @@ describe('ElasticDatasource', function(this: any) {
}),
};
const ctx = <any>{
const ctx = {
$rootScope,
backendSrv,
};
} as any;
function createDatasource(instanceSettings) {
instanceSettings.jsonData = instanceSettings.jsonData || {};
......
......@@ -3,7 +3,7 @@ import gfunc from '../gfunc';
import { GraphiteQueryCtrl } from '../query_ctrl';
describe('GraphiteQueryCtrl', () => {
const ctx = <any>{
const ctx = {
datasource: {
metricFindQuery: jest.fn(() => Promise.resolve([])),
getFuncDefs: jest.fn(() => Promise.resolve(gfunc.getFuncDefs('1.0'))),
......@@ -15,7 +15,7 @@ describe('GraphiteQueryCtrl', () => {
panelCtrl: {
refresh: jest.fn(),
},
};
} as any;
ctx.panelCtrl.panel = {
targets: [ctx.target],
......
......@@ -3,7 +3,7 @@ import { uiSegmentSrv } from 'app/core/services/segment_srv';
import { InfluxQueryCtrl } from '../query_ctrl';
describe('InfluxDBQueryCtrl', () => {
const ctx = <any>{};
const ctx = {} as any;
beforeEach(() => {
InfluxQueryCtrl.prototype.datasource = {
......
......@@ -9,9 +9,9 @@ describe('MySQLDatasource', function() {
replace: jest.fn(text => text),
};
const ctx = <any>{
const ctx = {
backendSrv,
};
} as any;
beforeEach(() => {
ctx.ds = new MysqlDatasource(instanceSettings, backendSrv, {}, templateSrv);
......
......@@ -2,13 +2,13 @@ import OpenTsDatasource from '../datasource';
import $q from 'q';
describe('opentsdb', () => {
const ctx = <any>{
const ctx = {
backendSrv: {},
ds: {},
templateSrv: {
replace: str => str,
},
};
} as any;
const instanceSettings = { url: '', jsonData: { tsdbVersion: 1 } };
beforeEach(() => {
......
import { OpenTsQueryCtrl } from '../query_ctrl';
describe('OpenTsQueryCtrl', () => {
const ctx = <any>{
const ctx = {
target: { target: '' },
datasource: {
tsdbVersion: '',
getAggregators: () => Promise.resolve([]),
getFilterTypes: () => Promise.resolve([]),
},
};
} as any;
ctx.panelCtrl = {
panel: {
......
......@@ -9,9 +9,9 @@ describe('PostgreSQLDatasource', function() {
const templateSrv = {
replace: jest.fn(text => text),
};
const ctx = <any>{
const ctx = {
backendSrv,
};
} as any;
beforeEach(() => {
ctx.ds = new PostgresDatasource(instanceSettings, backendSrv, {}, templateSrv);
......
......@@ -15,7 +15,7 @@ describe('Prometheus editor completer', function() {
const editor = {};
const backendSrv = <BackendSrv>{};
const backendSrv = {} as BackendSrv;
const datasourceStub = new PrometheusDatasource({}, {}, backendSrv, {}, {});
datasourceStub.performInstantQuery = jest.fn(() =>
......
......@@ -385,7 +385,7 @@ const HOUR = 60 * MINUTE;
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => moment(hours * HOUR + minutes * MINUTE + seconds * SECOND);
const ctx = <any>{};
const ctx = {} as any;
const instanceSettings = {
url: 'proxied',
directUrl: 'direct',
......@@ -393,9 +393,9 @@ const instanceSettings = {
password: 'mupp',
jsonData: { httpMethod: 'GET' },
};
const backendSrv = <any>{
const backendSrv = {
datasourceRequest: jest.fn(),
};
} as any;
const templateSrv = {
replace: jest.fn(str => str),
......@@ -435,7 +435,7 @@ describe('PrometheusDatasource', () => {
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
......@@ -485,7 +485,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
......@@ -546,7 +546,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
......@@ -601,7 +601,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.annotationQuery(options).then(function(data) {
results = data;
......@@ -641,7 +641,7 @@ describe('PrometheusDatasource', () => {
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
......@@ -678,7 +678,7 @@ describe('PrometheusDatasource', () => {
const urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=10';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -694,7 +694,7 @@ describe('PrometheusDatasource', () => {
};
const urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=1';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -715,7 +715,7 @@ describe('PrometheusDatasource', () => {
};
const urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=10';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -732,7 +732,7 @@ describe('PrometheusDatasource', () => {
const start = 60 * 60;
const urlExpected = 'proxied/api/v1/query_range?query=test&start=' + start + '&end=' + end + '&step=2';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -754,7 +754,7 @@ describe('PrometheusDatasource', () => {
// times get rounded up to interval
const urlExpected = 'proxied/api/v1/query_range?query=test&start=50&end=450&step=50';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -775,7 +775,7 @@ describe('PrometheusDatasource', () => {
};
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=60&end=420&step=15';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -797,7 +797,7 @@ describe('PrometheusDatasource', () => {
// times get aligned to interval
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=0&end=500&step=100';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -819,7 +819,7 @@ describe('PrometheusDatasource', () => {
const start = 0;
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=' + start + '&end=' + end + '&step=100';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -841,7 +841,7 @@ describe('PrometheusDatasource', () => {
const start = 0;
const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=' + start + '&end=' + end + '&step=60';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -884,7 +884,7 @@ describe('PrometheusDatasource', () => {
templateSrv.replace = jest.fn(str => str);
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -923,7 +923,7 @@ describe('PrometheusDatasource', () => {
'&start=60&end=420&step=10';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -963,7 +963,7 @@ describe('PrometheusDatasource', () => {
'&start=0&end=500&step=100';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -1009,7 +1009,7 @@ describe('PrometheusDatasource', () => {
templateSrv.replace = jest.fn(str => str);
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -1049,7 +1049,7 @@ describe('PrometheusDatasource', () => {
'&start=60&end=420&step=15';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -1094,7 +1094,7 @@ describe('PrometheusDatasource', () => {
'&step=60';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query);
const res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('GET');
......@@ -1155,7 +1155,7 @@ describe('PrometheusDatasource for POST', () => {
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
......
......@@ -28,7 +28,7 @@ import moment from 'moment';
import $ from 'jquery';
import { graphDirective } from '../graph';
const ctx = <any>{};
const ctx = {} as any;
let ctrl;
const scope = {
ctrl: {},
......@@ -47,7 +47,7 @@ describe('grafanaGraph', function() {
lightTheme: false,
},
};
GraphCtrl.prototype = <any>{
GraphCtrl.prototype = {
...MetricsPanelCtrl.prototype,
...PanelCtrl.prototype,
...GraphCtrl.prototype,
......@@ -88,7 +88,7 @@ describe('grafanaGraph', function() {
from: moment([2015, 1, 1, 10]),
to: moment([2015, 1, 1, 22]),
},
};
} as any;
ctx.data = [];
ctx.data.push(
......
......@@ -30,7 +30,7 @@ describe('GraphCtrl', () => {
},
};
const ctx = <any>{};
const ctx = {} as any;
beforeEach(() => {
ctx.ctrl = new GraphCtrl(scope, injector, {});
......
......@@ -2,7 +2,7 @@ import moment from 'moment';
import { HeatmapCtrl } from '../heatmap_ctrl';
describe('HeatmapCtrl', function() {
const ctx = <any>{};
const ctx = {} as any;
const $injector = {
get: () => {},
......
......@@ -2,7 +2,7 @@ import { SingleStatCtrl } from '../module';
import moment from 'moment';
describe('SingleStatCtrl', function() {
const ctx = <any>{};
const ctx = {} as any;
const epoch = 1505826363746;
Date.now = () => epoch;
......
......@@ -21,7 +21,7 @@ angular.module('grafana.directives', []);
angular.module('grafana.filters', []);
angular.module('grafana.routes', ['ngRoute']);
const context = (<any>require).context('../', true, /specs\.(tsx?|js)/);
const context = (require as any).context('../', true, /specs\.(tsx?|js)/);
for (const key of context.keys()) {
context(key);
}
......@@ -18,5 +18,5 @@ jest.mock('app/features/plugins/plugin_loader', () => ({}));
configure({ adapter: new Adapter() });
const global = <any>window;
const global = window as any;
global.$ = global.jQuery = $;
declare var global: NodeJS.Global;
(<any>global).requestAnimationFrame = callback => {
(global as any).requestAnimationFrame = callback => {
setTimeout(callback, 0);
};
(<any>Promise.prototype).finally = function(onFinally) {
(Promise.prototype as any).finally = function(onFinally) {
return this.then(
/* onFulfilled */
res => Promise.resolve(onFinally()).then(() => res),
......
const _global = <any>window;
const _global = window as any;
const beforeEach = _global.beforeEach;
const afterEach = _global.afterEach;
const before = _global.before;
......
......@@ -29,6 +29,7 @@
"label-position": true,
"max-line-length": [true, 150],
"member-access": [true, "no-public"],
"no-angle-bracket-type-assertion": true,
"no-arg": true,
"no-bitwise": false,
"no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment