mirror of
https://github.com/jsbin/jsbin.git
synced 2026-02-01 16:46:05 +00:00
Merge pull request #1809 from jsbin/feature/reported-bins
Feature/reported bins
This commit is contained in:
commit
9ec07a83ca
@ -33,7 +33,7 @@
|
||||
"getUserForForgotToken": "SELECT `ownership`.*, expires FROM `ownership` INNER JOIN `forgot_tokens` ON `name` = `owner_name` WHERE `token` = ? AND `forgot_tokens`.`expires` >= ?",
|
||||
"setForgotToken": "INSERT INTO `forgot_tokens` (`owner_name`, `token`, `expires`, `created`) VALUES (?, ?, ?, ?)",
|
||||
"deleteExpiredForgotToken": "DELETE FROM `forgot_tokens` WHERE `expires` <= ? OR `token`=? OR `owner_name`=?",
|
||||
"reportBin": "UPDATE `sandbox` SET `reported`=? WHERE `url`=? AND `revision`=? AND `active`='y'",
|
||||
"reportBin": "UPDATE `sandbox` SET `reported`=?, `active`='n' WHERE `url`=? AND `revision`=? AND `reported` IS NULL",
|
||||
"updateBinData": "UPDATE `sandbox` SET `:field`=? WHERE `url`=? AND `revision`=?",
|
||||
"updateOwnersData": "UPDATE `owners` SET `:field`=? WHERE `url`=? AND `revision`=?",
|
||||
"updateOwnershipData": "UPDATE `ownership` SET `:field`=? WHERE `name`=?",
|
||||
|
||||
@ -53,6 +53,14 @@ exports.NotFound = HTTPError.extend({
|
||||
}
|
||||
});
|
||||
|
||||
// Creates an error object for handling 404 responses.
|
||||
exports.Reported = HTTPError.extend({
|
||||
constructor: function NotFound(message) {
|
||||
HTTPError.call(this, 404, message);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
exports.BinNotFound = exports.NotFound.extend({
|
||||
constructor: function BinNotFound(message) {
|
||||
exports.NotFound.call(this, 404, message);
|
||||
|
||||
@ -397,9 +397,9 @@ module.exports = Observable.extend({
|
||||
return res.redirect(root);
|
||||
}
|
||||
return next(new errors.BinNotFound('Could not find bin: ' + req.params.bin));
|
||||
} else if (!bin.active) {
|
||||
} else if (!bin.active && bin.reported) {
|
||||
metrics.increment('bin.404-reported');
|
||||
return next(new errors.NotFound('Bin has been reported: ' + req.params.bin));
|
||||
return next(new errors.Reported('Bin has been reported: ' + req.params.bin));
|
||||
} else {
|
||||
req.bin = bin;
|
||||
next();
|
||||
@ -807,10 +807,10 @@ module.exports = Observable.extend({
|
||||
|
||||
if (!result || err === 401) {
|
||||
metrics.increment('bin.404');
|
||||
return next(new errors.BinNotFound('Could not find bin: ' + req.params.bin));
|
||||
} else if (!result.active) {
|
||||
return next(new errors.NotFound('Could not find bin: ' + req.params.bin));
|
||||
} else if (!result.active && result.reported) {
|
||||
metrics.increment('bin.404-reported');
|
||||
return next(new errors.NotFound('Bin has been reported: ' + req.params.bin));
|
||||
return next(new errors.Reported('Bin has been reported: ' + req.params.bin));
|
||||
} else {
|
||||
var flag = undefsafe(result, 'metadata.flagged');
|
||||
if (flag) {
|
||||
|
||||
@ -25,22 +25,25 @@ module.exports = Observable.extend({
|
||||
|
||||
if (err instanceof errors.NotFound && req.accepts('html')) {
|
||||
if (err instanceof errors.BinNotFound) {
|
||||
return (new BinHandler(this.sandbox)).notFound(req, res, next);
|
||||
return this.renderErrorPage('error', err, req, res);
|
||||
// return (new BinHandler(this.sandbox)).notFound(req, res, next);
|
||||
} else {
|
||||
return this.renderErrorPage(err, req, res);
|
||||
return this.renderErrorPage('error', err, req, res);
|
||||
}
|
||||
next(err);
|
||||
} else if (err instanceof errors.HTTPError) {
|
||||
return this.renderError(err, req, res);
|
||||
// return this.renderError(err, req, res);
|
||||
return this.renderErrorPage(err.status, err, req, res);
|
||||
next(err);
|
||||
}
|
||||
|
||||
next(err);
|
||||
},
|
||||
|
||||
// Fall through handler for when no routes match.
|
||||
notFound: function (req, res) {
|
||||
var error = new errors.NotFound('Page Does Not Exist');
|
||||
if (req.accepts('html') && (req.url.indexOf('/api/') !== 0)) {
|
||||
this.renderErrorPage(error, req, res);
|
||||
this.renderErrorPage('404', error, req, res);
|
||||
} else {
|
||||
this.renderError(error, req, res);
|
||||
}
|
||||
@ -53,7 +56,7 @@ module.exports = Observable.extend({
|
||||
this.sendErrorReport(err, req);
|
||||
|
||||
if (req.accepts('html')) {
|
||||
this.renderErrorPage(err, req, res);
|
||||
this.renderErrorPage('error', err, req, res);
|
||||
} else {
|
||||
var error = new errors.HTTPError(500, 'Internal Server Error');
|
||||
this.renderError(error, req, res);
|
||||
@ -74,10 +77,12 @@ module.exports = Observable.extend({
|
||||
}
|
||||
},
|
||||
|
||||
renderErrorPage: function (err, req, res) {
|
||||
renderErrorPage: function (view, err, req, res) {
|
||||
var status = err.status || 500;
|
||||
|
||||
res.status(status).render('error', {
|
||||
var views = ['error', 504, 502];
|
||||
|
||||
res.status(status).render(views.indexOf(view) !== -1 ? view : 'error', {
|
||||
is_500: status !== 404, // Saves us having many error pages at the mo.
|
||||
is_404: status === 404,
|
||||
root: this.helpers.url('', true),
|
||||
|
||||
@ -181,7 +181,12 @@ module.exports = function (app) {
|
||||
});
|
||||
|
||||
next();
|
||||
}, userHandler.updateLastSeen, binHandler.loadBin);
|
||||
}, userHandler.updateLastSeen, binHandler.loadBin, function (req, res, next) {
|
||||
if (req.bin) {
|
||||
app.emit('bin:loaded', req);
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
// track the logged in and logged out numbers
|
||||
app.get('*', function (req, res, next) {
|
||||
@ -555,7 +560,8 @@ module.exports = function (app) {
|
||||
app.get('/:bin/:rev?/watch', tag('live'), binHandler.getBin);
|
||||
app.get('/:bin/:rev?/embed', tag('embed'), binHandler.getBin);
|
||||
|
||||
app.post('/:bin/:rev?/report', binHandler.report);
|
||||
// don't expose anymore - reporting goes through github
|
||||
// app.post('/:bin/:rev?/report', binHandler.report);
|
||||
|
||||
// Use this handler to check for a user creating/claiming their own bin url.
|
||||
// We use :url here to prevent loadBin() being called and returning a not
|
||||
|
||||
@ -272,6 +272,6 @@ module.exports = {
|
||||
return str;
|
||||
},
|
||||
binUrlLength: function (req) {
|
||||
return undefsafe(req, 'session.user') ? 2 : 7;
|
||||
return undefsafe(req, 'session.user') ? 2 : 11;
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,63 +1,30 @@
|
||||
html {
|
||||
background: rgb(250, 250, 250);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
background: #3FA8C6;
|
||||
background: -moz-linear-gradient(top, #3fa8c6 0%, #3fa8c6 0%, #399ab2 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3fa8c6), color-stop(0%,#3fa8c6), color-stop(100%,#399ab2));
|
||||
background: -webkit-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
|
||||
background: -o-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
|
||||
background: -ms-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
|
||||
background: linear-gradient(to bottom, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
|
||||
background-color: #399AB2;
|
||||
background-repeat: repeat-x;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 rgba(0,0,0,.3);
|
||||
font-family: 'helvetica neue', sans-serif;
|
||||
font-size: 18px;
|
||||
color: #111111;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
margin: 40px auto;
|
||||
max-width: 660px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
letter-spacing: -0.03em;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #fff;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.7);
|
||||
padding-bottom: 0.15em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
a:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -2px;
|
||||
background: rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #C0E3EC;
|
||||
div.wrapper {
|
||||
margin-left: 128px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: left;
|
||||
letter-spacing: -0.03em;
|
||||
font-size: 2em;
|
||||
margin: 0.667em 0 0;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
small {
|
||||
@ -67,76 +34,19 @@ small {
|
||||
font-size: 0.667em;
|
||||
}
|
||||
|
||||
p em {
|
||||
font-style: none;
|
||||
}
|
||||
|
||||
#welcome {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding-bottom: 1em;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
#welcome > div {
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
#dave {
|
||||
height: 128px;
|
||||
float: left;
|
||||
margin-top: 3em
|
||||
user-drag: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
|
||||
#welcome > h2 {
|
||||
margin-top: 0.5em;
|
||||
padding-left: 0.5em;
|
||||
margin-bottom: 0;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.bubble p {
|
||||
line-height: 22px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
|
||||
padding: 0.667em 1em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bubble:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 20px solid transparent;
|
||||
border-bottom: 20px solid transparent;
|
||||
border-right: 20px solid white;
|
||||
border-right-color: inherit;
|
||||
top: 50px;
|
||||
left: -20px;
|
||||
}
|
||||
|
||||
img {
|
||||
z-index: 1;
|
||||
-webkit-transition: -webkit-transform 2s ease-in-out;
|
||||
-moz-transition: -moz-transform 2s ease-in-out;
|
||||
-o-transition: -o-transform 2s ease-in-out;
|
||||
-ms-transition: -ms-transform 2s ease-in-out;
|
||||
transition: transform 2s ease-in-out;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
img:active {
|
||||
-webkit-transform: rotate(1440deg) scale(1.2);
|
||||
-moz-transform: rotate(1440deg) scale(1.2);
|
||||
-o-transform: rotate(1440deg) scale(1.2);
|
||||
-ms-transform: rotate(1440deg) scale(1.2);
|
||||
transform: rotate(1440deg) scale(1.2);
|
||||
}
|
||||
|
||||
pre {
|
||||
@ -148,50 +58,27 @@ pre {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.wrapper {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.wrapper {
|
||||
@media screen and (max-width: 660px) {
|
||||
html {
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
#welcome {
|
||||
margin-right: 2.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
.wrapper {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#dave {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#welcome {
|
||||
padding: 0 1.5em;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
font-size: 1.8em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#welcome > h2 {
|
||||
margin-bottom: 0.667em;
|
||||
body {
|
||||
margin: 10px auto;
|
||||
padding: 10px;
|
||||
}
|
||||
.bubble {
|
||||
text-align: center;
|
||||
}
|
||||
.bubble:after {
|
||||
|
||||
img {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
div.wrapper {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
1
public/images/dave.min.svg
Normal file
1
public/images/dave.min.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.5 KiB |
@ -14,12 +14,12 @@ function jsbinShowEdit(options) {
|
||||
btn.id = 'edit-with-js-bin';
|
||||
btn.href = path + (path.slice(-1) === '/' ? '' : '/') + 'edit';
|
||||
btn.innerHTML = 'Edit in JS Bin <img src="' + options['static'] + '/images/favicon.png" width="16" height="16">';
|
||||
doc.body.appendChild(btn);
|
||||
doc.documentElement.appendChild(btn);
|
||||
|
||||
// Style button:
|
||||
style.setAttribute('rel', 'stylesheet');
|
||||
style.setAttribute('href', options['static'] + '/css/edit.css');
|
||||
doc.getElementsByTagName('head')[0].appendChild(style);
|
||||
doc.documentElement.appendChild(style);
|
||||
|
||||
|
||||
// show / hide button:
|
||||
|
||||
@ -6,16 +6,12 @@
|
||||
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
|
||||
</head>
|
||||
<body>
|
||||
<img id="dave" src="{{static}}/images/jsbin_static.png" alt="Dave, the JS Bin bot">
|
||||
<div class="wrapper">
|
||||
<img id="dave" src="{{static}}/images/jsbin_static.png" alt="Dave, the JS Bin bot">
|
||||
<div id="welcome">
|
||||
<h1>502: Dave's left the building</h1>
|
||||
<div class="bubble">
|
||||
<p>JS Bin isn't available right now. Someone should be working on it,
|
||||
and you can check the current status on <a href="http://status.jsbin.com">status.jsbin.com</a>, but do feel free to <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20it%20looks%20like%20you're%20currently%20down%20(502).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a>.</p>
|
||||
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this atrocity.</p>
|
||||
</div>
|
||||
</div>
|
||||
<h1>502: Dave's left the building</h1>
|
||||
<p>JS Bin isn't available right now. Someone should be working on it,
|
||||
and you can check the current status on <a href="http://status.jsbin.com">status.jsbin.com</a>, but do feel free to <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20it%20looks%20like%20you're%20currently%20down%20(502).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a>.</p>
|
||||
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this atrocity.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -6,16 +6,12 @@
|
||||
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
|
||||
</head>
|
||||
<body>
|
||||
<img id="dave" src="{{static}}/images/dave.min.svg" alt="Dave, the JS Bin bot">
|
||||
<div class="wrapper">
|
||||
<img id="dave" src="{{static}}/images/jsbin_static.png" alt="Dave, the JS Bin bot">
|
||||
<div id="welcome">
|
||||
<h1>504: Dave didn't come back quickly enough</h1>
|
||||
<div class="bubble">
|
||||
<p>This is embarrassing, you've asked for something and I've spent too long getting it. Maybe I got distracted by some pretty lights, but you'll never know.</p>
|
||||
<p>Do check <a href="http://status.jsbin.com">status.jsbin.com</a>, but do <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20you're%20taking%20too%20long%20to%20respond%20to%20requests%20(504).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a> if this problem keeps happening.</p>
|
||||
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this slackness.</p>
|
||||
</div>
|
||||
</div>
|
||||
<h1>504: Dave didn't come back quickly enough</h1>
|
||||
<p>This is embarrassing, you've asked for something and I've spent too long getting it. Maybe I got distracted by some pretty lights, but you'll never know.</p>
|
||||
<p>Do check <a href="http://status.jsbin.com">status.jsbin.com</a>, but do <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20you're%20taking%20too%20long%20to%20respond%20to%20requests%20(504).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a> if this problem keeps happening.</p>
|
||||
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this slackness.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -2,40 +2,38 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Uh-oh Something Went Wrong</title>
|
||||
<title>404: JS Bin not found</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
|
||||
</head>
|
||||
<body>
|
||||
<img id="dave" src="{{static}}/images/dave.min.svg" alt="Dave, the JS Bin bot">
|
||||
<div class="wrapper">
|
||||
<img id="dave" src="{{static}}/images/logo.png" alt="Dave, the JS Bin bot">
|
||||
<div id="welcome">
|
||||
{{#is_404}}
|
||||
<h1>This page isn't here :-(</h1>
|
||||
<div class="bubble">
|
||||
<p>How about heading back to the <a href="{{root}}">homepage</a>
|
||||
instead? It's nice there and there are lots of things to click on.</p>
|
||||
<p>If you think there is supposed to be something here that isn't
|
||||
let us know via the <a href="http://github.com/jsbin/jsbin/issues">Issues page</a>.</p>
|
||||
</div>
|
||||
{{/is_404}}
|
||||
{{#is_500}}<h1>Oh no!<br />Something went wrong!</h1>
|
||||
<p class="bubble">But don't worry we're probably on the case. In the
|
||||
meantime you could try refreshing the page, if that doesn't work
|
||||
let us know by creating an issue on the <a href="http://github.com/jsbin/jsbin/issues">Issues page</a>.</p>
|
||||
{{#if is_404}}
|
||||
<h1>This page isn't here :-(</h1>
|
||||
<p>How about heading back to the <a href="{{root}}">homepage</a>
|
||||
instead? It's nice there and there are lots of things to click on.</p>
|
||||
<p>If you think there is supposed to be something here that isn't
|
||||
let us know via the <a href="http://github.com/jsbin/jsbin/issues">Issues page</a>.</p>
|
||||
{{/if}}
|
||||
{{#if is_500}}
|
||||
<h1>Something went wrong!</h1>
|
||||
<p>But don't worry we're probably on the case. In the
|
||||
meantime you could try refreshing the page, if that doesn't work
|
||||
let us know by creating an issue on the <a href="http://github.com/jsbin/jsbin/issues">issues page</a>.</p>
|
||||
<!--
|
||||
{{err}}
|
||||
|
||||
{{stack}}
|
||||
-->
|
||||
{{/is_500}}
|
||||
</div>
|
||||
{{#is_500}}
|
||||
{{/if}}
|
||||
{{#if is_500}}
|
||||
<details>
|
||||
<summary>The error: {{err}}</summary>
|
||||
<pre>{{request.method}} {{request.url}}
|
||||
{{stack}}</pre>
|
||||
</details>
|
||||
{{/is_500}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="toppanel-column toppanel-column-first">
|
||||
<a href="#" class="toppanel-hide" title="Close">Close welcome panel</a>
|
||||
<a href="#" class="toppanel-logo">
|
||||
<img src="{{static}}/images/dave.svg" alt="Welcome to JS Bin">
|
||||
<img src="{{static}}/images/dave.min.svg" alt="Welcome to JS Bin">
|
||||
</a>
|
||||
<div class="toppanel-actions{{#unless home}} toppanel-actions-alone{{/unless}}">
|
||||
<div>
|
||||
|
||||
16
views/reported.html
Normal file
16
views/reported.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>JS Bin - reported content</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
|
||||
</head>
|
||||
<body>
|
||||
<img id="dave" src="{{static}}/images/dave.min.svg" height="128" alt="Dave, the JS Bin bot">
|
||||
<div class="wrapper">
|
||||
<h1>This bin has been reported</h1>
|
||||
<p>This bin has been reported as suspicious in content, and has been forboden from being part of the web.</p>
|
||||
<p>If you believe this to be a mistake, please raise an <a href="http://github.com/jsbin/jsbin/issues/new?title=Incorrectly reported bin&body=Bin url: {{root}}{{request.url}}">issue</a> and add any additional information you can to help diagnose this atrocity.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user