fix grid layout in IE 11
this brings back index addressing rather than x y in the grid vm, as we need to have a css class for every position for IE 11, as we can't use css variables and autoprefixer can translate grid-areas
This commit is contained in:
parent
c4cfb6f6d1
commit
47a43869e6
6 changed files with 142 additions and 60 deletions
|
@ -29,13 +29,14 @@
|
|||
"@rollup/plugin-commonjs": "^15.0.0",
|
||||
"@rollup/plugin-multi-entry": "^4.0.0",
|
||||
"@rollup/plugin-node-resolve": "^9.0.0",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"commander": "^6.0.0",
|
||||
"core-js": "^3.6.5",
|
||||
"finalhandler": "^1.1.1",
|
||||
"impunity": "^1.0.0",
|
||||
"mdn-polyfills": "^5.20.0",
|
||||
"postcss": "^7.0.32",
|
||||
"postcss": "^8.1.1",
|
||||
"postcss-css-variables": "^0.17.0",
|
||||
"postcss-flexbugs-fixes": "^4.2.1",
|
||||
"postcss-import": "^12.0.1",
|
||||
|
@ -47,11 +48,11 @@
|
|||
"xxhashjs": "^0.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"es6-promise": "https://github.com/bwindels/es6-promise.git#bwindels/expose-flush",
|
||||
"aes-js": "^3.1.2",
|
||||
"another-json": "^0.2.0",
|
||||
"base64-arraybuffer": "^0.2.0",
|
||||
"bs58": "^4.0.1",
|
||||
"es6-promise": "https://github.com/bwindels/es6-promise.git#bwindels/expose-flush",
|
||||
"olm": "https://packages.matrix.org/npm/olm/olm-3.1.4.tgz",
|
||||
"text-encoding": "^0.7.0"
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import removeJsComments from 'rollup-plugin-cleanup';
|
|||
import postcssUrl from "postcss-url";
|
||||
|
||||
import cssvariables from "postcss-css-variables";
|
||||
import autoprefixer from "autoprefixer";
|
||||
import flexbugsFixes from "postcss-flexbugs-fixes";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
|
@ -302,6 +303,8 @@ async function buildCssLegacy(entryPath, urlMapper = null) {
|
|||
const preCss = await fs.readFile(entryPath, "utf8");
|
||||
const options = [
|
||||
postcssImport,
|
||||
cssvariables(),
|
||||
autoprefixer({overrideBrowserslist: ["IE 11"], grid: "no-autoplace"}),
|
||||
flexbugsFixes()
|
||||
];
|
||||
if (urlMapper) {
|
||||
|
|
|
@ -25,39 +25,15 @@ export class RoomGridViewModel extends ViewModel {
|
|||
this._viewModels = [];
|
||||
}
|
||||
|
||||
_posToIdx(x, y) {
|
||||
return (y * this.width) + x;
|
||||
roomViewModelAt(i) {
|
||||
return this._viewModels[i]?.vm;
|
||||
}
|
||||
|
||||
_idxToX(idx) {
|
||||
return idx % this.width;
|
||||
get focusIndex() {
|
||||
return this._selectedIndex;
|
||||
}
|
||||
|
||||
_idxToY(idx) {
|
||||
return Math.floor(idx / this.width);
|
||||
}
|
||||
|
||||
roomViewModelAt(x, y) {
|
||||
return this._viewModels[this._posToIdx(x, y)]?.vm;
|
||||
}
|
||||
|
||||
get focusX() {
|
||||
return this._idxToX(this._selectedIndex);
|
||||
}
|
||||
|
||||
get focusY() {
|
||||
return this._idxToY(this._selectedIndex);
|
||||
}
|
||||
|
||||
isFocusAt(x, y) {
|
||||
return this._posToIdx(x, y) === this._selectedIndex;
|
||||
}
|
||||
|
||||
setFocusAt(x, y) {
|
||||
this._setFocusedIndex(this._posToIdx(x, y));
|
||||
}
|
||||
|
||||
_setFocusedIndex(idx) {
|
||||
setFocusIndex(idx) {
|
||||
if (idx === this._selectedIndex) {
|
||||
return;
|
||||
}
|
||||
|
@ -99,7 +75,7 @@ export class RoomGridViewModel extends ViewModel {
|
|||
tryFocusRoom(roomId) {
|
||||
const index = this._viewModels.findIndex(vms => vms?.vm._room.id === roomId);
|
||||
if (index >= 0) {
|
||||
this._setFocusedIndex(index);
|
||||
this.setFocusIndex(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -94,16 +94,26 @@ html {
|
|||
|
||||
.RoomGridView {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
grid-template-rows: repeat(var(--rows), 1fr);
|
||||
}
|
||||
|
||||
.RoomGridView.layout3x2 {
|
||||
grid-template:
|
||||
"t0 t1 t2" 1fr
|
||||
"t3 t4 t5" 1fr /
|
||||
1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
.RoomGridView > .tile0 {grid-area: t0;}
|
||||
.RoomGridView > .tile1 {grid-area: t1;}
|
||||
.RoomGridView > .tile2 {grid-area: t2;}
|
||||
.RoomGridView > .tile3 {grid-area: t3;}
|
||||
.RoomGridView > .tile4 {grid-area: t4;}
|
||||
.RoomGridView > .tile5 {grid-area: t5;}
|
||||
|
||||
.RoomGridView > div {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
grid-column: var(--column);
|
||||
grid-row: var(--row);
|
||||
}
|
||||
|
||||
.RoomGridView > div.focus-ring {
|
||||
|
|
|
@ -21,29 +21,24 @@ import {TemplateView} from "../general/TemplateView.js";
|
|||
export class RoomGridView extends TemplateView {
|
||||
render(t, vm) {
|
||||
const children = [];
|
||||
for (let y = 0; y < vm.height; y+=1) {
|
||||
for (let x = 0; x < vm.width; x+=1) {
|
||||
children.push(t.div({
|
||||
onClick: () => vm.setFocusAt(x, y),
|
||||
onFocusin: () => vm.setFocusAt(x, y),
|
||||
className: {
|
||||
"container": true,
|
||||
"focused": vm => vm.isFocusAt(x, y)
|
||||
},
|
||||
style: `--column: ${x + 1}; --row: ${y + 1}`
|
||||
},t.mapView(vm => vm.roomViewModelAt(x, y), roomVM => {
|
||||
if (roomVM) {
|
||||
return new RoomView(roomVM);
|
||||
} else {
|
||||
return new RoomPlaceholderView();
|
||||
}
|
||||
})));
|
||||
}
|
||||
for (let i = 0; i < (vm.height * vm.width); i+=1) {
|
||||
children.push(t.div({
|
||||
onClick: () => vm.setFocusIndex(i),
|
||||
onFocusin: () => vm.setFocusIndex(i),
|
||||
className: {
|
||||
"container": true,
|
||||
[`tile${i}`]: true,
|
||||
"focused": vm => vm.focusIndex === i
|
||||
},
|
||||
},t.mapView(vm => vm.roomViewModelAt(i), roomVM => {
|
||||
if (roomVM) {
|
||||
return new RoomView(roomVM);
|
||||
} else {
|
||||
return new RoomPlaceholderView();
|
||||
}
|
||||
})));
|
||||
}
|
||||
children.push(t.div({className: "focus-ring", style: vm => `--column: ${vm.focusX + 1}; --row: ${vm.focusY + 1}`}));
|
||||
return t.div({
|
||||
className: "RoomGridView",
|
||||
style: `--columns: ${vm.width}; --rows: ${vm.height}`
|
||||
}, children);
|
||||
children.push(t.div({className: vm => `focus-ring tile${vm.focusIndex}`}));
|
||||
return t.div({className: "RoomGridView layout3x2"}, children);
|
||||
}
|
||||
}
|
||||
|
|
99
yarn.lock
99
yarn.lock
|
@ -933,6 +933,18 @@ ansi-styles@^3.2.1:
|
|||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
autoprefixer@^10.0.1:
|
||||
version "10.0.1"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.0.1.tgz#e2d9000f84ebd98d77b7bc16f8adb2ff1f7bb946"
|
||||
integrity sha512-aQo2BDIsoOdemXUAOBpFv4ZQa2DrOtEufarYhtFsK1088Ca0TUwu/aQWf0M3mrILXZ3mTIVn1lR3hPW8acacsw==
|
||||
dependencies:
|
||||
browserslist "^4.14.5"
|
||||
caniuse-lite "^1.0.30001137"
|
||||
colorette "^1.2.1"
|
||||
normalize-range "^0.1.2"
|
||||
num2fraction "^1.2.2"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
babel-plugin-dynamic-import-node@^2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3"
|
||||
|
@ -980,6 +992,16 @@ browserslist@^4.12.0, browserslist@^4.8.5:
|
|||
escalade "^3.0.2"
|
||||
node-releases "^1.1.60"
|
||||
|
||||
browserslist@^4.14.5:
|
||||
version "4.14.5"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.5.tgz#1c751461a102ddc60e40993639b709be7f2c4015"
|
||||
integrity sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001135"
|
||||
electron-to-chromium "^1.3.571"
|
||||
escalade "^3.1.0"
|
||||
node-releases "^1.1.61"
|
||||
|
||||
bs58@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
|
||||
|
@ -997,6 +1019,11 @@ caniuse-lite@^1.0.30001111:
|
|||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001115.tgz#c04cd828883ba47f6f776312e0817bcc9040cfa4"
|
||||
integrity sha512-NZrG0439ePYna44lJX8evHX2L7Z3/z3qjVLnHgbBb/duNEnGo348u+BQS5o4HTWcrb++100dHFrU36IesIrC1Q==
|
||||
|
||||
caniuse-lite@^1.0.30001135, caniuse-lite@^1.0.30001137:
|
||||
version "1.0.30001144"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001144.tgz#bca0fffde12f97e1127a351fec3bfc1971aa3b3d"
|
||||
integrity sha512-4GQTEWNMnVZVOFG3BK0xvGeaDAtiPAbG2N8yuMXuXzx/c2Vd4XoMPO8+E918zeXn5IF0FRVtGShBfkfQea2wHQ==
|
||||
|
||||
chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
|
@ -1030,6 +1057,11 @@ color-name@1.1.3:
|
|||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
colorette@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
|
||||
integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
|
||||
|
||||
colors@^1.3.3:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
||||
|
@ -1190,6 +1222,11 @@ electron-to-chromium@^1.3.523:
|
|||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.534.tgz#fc7af8518dd00a5b22a24aed3f116b5d097e2330"
|
||||
integrity sha512-7x2S3yUrspNHQOoPk+Eo+iHViSiJiEGPI6BpmLy1eT2KRNGCkBt/NUYqjfXLd1DpDCQp7n3+LfA1RkbG+LqTZQ==
|
||||
|
||||
electron-to-chromium@^1.3.571:
|
||||
version "1.3.578"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.578.tgz#e6671936f4571a874eb26e2e833aa0b2c0b776e0"
|
||||
integrity sha512-z4gU6dA1CbBJsAErW5swTGAaU2TBzc2mPAonJb00zqW1rOraDo2zfBMDRvaz9cVic+0JEZiYbHWPw/fTaZlG2Q==
|
||||
|
||||
encodeurl@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
|
@ -1214,6 +1251,11 @@ escalade@^3.0.2:
|
|||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
|
||||
integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==
|
||||
|
||||
escalade@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e"
|
||||
integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig==
|
||||
|
||||
escape-html@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
|
@ -1382,6 +1424,18 @@ is-reference@^1.2.1:
|
|||
dependencies:
|
||||
"@types/estree" "*"
|
||||
|
||||
isarray@1.0.0, isarray@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
|
||||
isobject@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
|
||||
integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=
|
||||
dependencies:
|
||||
isarray "1.0.0"
|
||||
|
||||
js-cleanup@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/js-cleanup/-/js-cleanup-1.0.1.tgz#1d38080c7ee92e1d2d2b94054d0a33c48951e0df"
|
||||
|
@ -1425,6 +1479,14 @@ levenary@^1.1.1:
|
|||
dependencies:
|
||||
leven "^3.1.0"
|
||||
|
||||
line-column@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/line-column/-/line-column-1.0.2.tgz#d25af2936b6f4849172b312e4792d1d987bc34a2"
|
||||
integrity sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=
|
||||
dependencies:
|
||||
isarray "^1.0.0"
|
||||
isobject "^2.0.0"
|
||||
|
||||
lodash@^4.15.0:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
|
@ -1506,11 +1568,26 @@ ms@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
nanoid@^3.1.12:
|
||||
version "3.1.12"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654"
|
||||
integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==
|
||||
|
||||
node-releases@^1.1.60:
|
||||
version "1.1.60"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084"
|
||||
integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==
|
||||
|
||||
node-releases@^1.1.61:
|
||||
version "1.1.61"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e"
|
||||
integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g==
|
||||
|
||||
normalize-range@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
||||
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
|
||||
|
||||
nth-check@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
|
||||
|
@ -1518,6 +1595,11 @@ nth-check@~1.0.1:
|
|||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
|
||||
num2fraction@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
||||
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
|
||||
|
||||
object-keys@^1.0.11, object-keys@^1.0.12:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||
|
@ -1631,6 +1713,11 @@ postcss-value-parser@^3.2.3:
|
|||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
|
||||
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
|
||||
|
||||
postcss-value-parser@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
|
||||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
|
||||
|
||||
postcss@^6.0.8:
|
||||
version "6.0.23"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324"
|
||||
|
@ -1649,7 +1736,7 @@ postcss@^7.0.1:
|
|||
source-map "^0.6.1"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.32:
|
||||
postcss@^7.0.2, postcss@^7.0.26:
|
||||
version "7.0.32"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
|
||||
integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==
|
||||
|
@ -1658,6 +1745,16 @@ postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.32:
|
|||
source-map "^0.6.1"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
postcss@^8.1.1:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.1.1.tgz#c3a287dd10e4f6c84cb3791052b96a5d859c9389"
|
||||
integrity sha512-9DGLSsjooH3kSNjTZUOt2eIj2ZTW0VI2PZ/3My+8TC7KIbH2OKwUlISfDsf63EP4aiRUt3XkEWMWvyJHvJelEg==
|
||||
dependencies:
|
||||
colorette "^1.2.1"
|
||||
line-column "^1.0.2"
|
||||
nanoid "^3.1.12"
|
||||
source-map "^0.6.1"
|
||||
|
||||
range-parser@~1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||
|
|
Reference in a new issue