init
This commit is contained in:
535
Gulpfile.js
Normal file
535
Gulpfile.js
Normal file
@@ -0,0 +1,535 @@
|
||||
|
||||
var shopconfig = require('./config.json');
|
||||
|
||||
var config = "";
|
||||
var shoptype = shopconfig.shoptype;
|
||||
|
||||
if(shoptype == 2) {
|
||||
config = shopconfig.b2b;
|
||||
}else {
|
||||
config = shopconfig.b2c;
|
||||
}
|
||||
|
||||
var insert = require('gulp-insert');
|
||||
|
||||
var bowerdir = config.bower.path,
|
||||
srcdir = config.layout.path + config.layout.code + "/" + config.layout.src,
|
||||
builddir = config.layout.path + config.layout.code + "/" + config.layout.build,
|
||||
distdir = config.layout.path + config.layout.code + "/" + config.layout.dist,
|
||||
fontName = config.iconfont.name,
|
||||
faviconTitle = config.favicon.title,
|
||||
faviconBackground = config.favicon.background,
|
||||
faviconColor = config.favicon.color,
|
||||
faviconMasterpicture = config.layout.path + config.layout.code + "/" + config.layout.src + "/" + config.favicon.masterpicture_path + config.favicon.masterpicture_filename,
|
||||
faviconDataFile = config.layout.path + config.layout.code + "/" + config.layout.dist + "/" + config.favicon.masterpicture_path + config.favicon.data_file;
|
||||
|
||||
var gulp = require('gulp'),
|
||||
changed = require('gulp-changed'),
|
||||
concat = require ('gulp-concat'),
|
||||
uglify = require ('gulp-uglify'),
|
||||
rename = require('gulp-rename'),
|
||||
imageMin = require ('gulp-imageMin'),
|
||||
clean = require('gulp-clean'),
|
||||
less = require ('gulp-less'),
|
||||
minifyCSS = require ('gulp-clean-css'),
|
||||
iconfont = require ('gulp-iconfont'),
|
||||
iconfontCss = require('gulp-iconfont-css'),
|
||||
realFavicon = require ('gulp-real-favicon'),
|
||||
fs = require('fs'),
|
||||
autoprefixer = require ('gulp-autoprefixer'),
|
||||
runSequence = require('run-sequence'),
|
||||
streamqueue = require('streamqueue'),
|
||||
sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
gulp.task('generate-iconfont', function(){
|
||||
gulp.src([srcdir + '/icons_svg/*.svg'])
|
||||
.pipe(iconfontCss({
|
||||
fontName: fontName,
|
||||
path: srcdir + '/less/template/_icons.less',
|
||||
targetPath: '../../../src/less/app/icons.less',
|
||||
fontPath: builddir + '/fonts/icons/'
|
||||
}))
|
||||
.pipe(iconfont({
|
||||
fontName: fontName
|
||||
}))
|
||||
.pipe(gulp.dest(builddir + '/fonts/icons/'));
|
||||
});
|
||||
|
||||
gulp.task('clean-dist',function () {
|
||||
return gulp.src(distdir, {read: false})
|
||||
.pipe(clean());
|
||||
})
|
||||
|
||||
gulp.task('generate-favicon', function(done) {
|
||||
realFavicon.generateFavicon({
|
||||
masterPicture: faviconMasterpicture,
|
||||
dest: distdir + '/favicons/',
|
||||
iconsPath: '/',
|
||||
design: {
|
||||
ios: {
|
||||
pictureAspect: 'noChange',
|
||||
assets: {
|
||||
ios6AndPriorIcons: false,
|
||||
ios7AndLaterIcons: false,
|
||||
precomposedIcons: false,
|
||||
declareOnlyDefaultIcon: true
|
||||
}
|
||||
},
|
||||
desktopBrowser: {},
|
||||
windows: {
|
||||
pictureAspect: 'noChange',
|
||||
backgroundColor: faviconBackground,
|
||||
onConflict: 'override',
|
||||
assets: {
|
||||
windows80Ie10Tile: false,
|
||||
windows10Ie11EdgeTiles: {
|
||||
small: false,
|
||||
medium: true,
|
||||
big: false,
|
||||
rectangle: false
|
||||
}
|
||||
}
|
||||
},
|
||||
androidChrome: {
|
||||
pictureAspect: 'noChange',
|
||||
themeColor: faviconBackground,
|
||||
manifest: {
|
||||
name: faviconTitle,
|
||||
display: 'standalone',
|
||||
orientation: 'notSet',
|
||||
onConflict: 'override',
|
||||
declared: true
|
||||
},
|
||||
assets: {
|
||||
legacyIcon: false,
|
||||
lowResolutionIcons: false
|
||||
}
|
||||
},
|
||||
safariPinnedTab: {
|
||||
pictureAspect: 'blackAndWhite',
|
||||
threshold: 82.8125,
|
||||
themeColor: faviconColor
|
||||
}
|
||||
},
|
||||
settings: {
|
||||
scalingAlgorithm: 'Mitchell',
|
||||
errorOnImageTooSmall: false
|
||||
},
|
||||
markupFile: distdir + "/favicons/faviconData.json"
|
||||
}, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('check-for-favicon-update', function(done) {
|
||||
var currentVersion = JSON.parse(fs.readFileSync(distdir + "/favicons/faviconData.json")).version;
|
||||
realFavicon.checkForUpdates(currentVersion, function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('minify-images', function() {
|
||||
var imgSrc = srcdir + '/images/**/*',
|
||||
imgDst = distdir + '/images/';
|
||||
|
||||
gulp.src(imgSrc)
|
||||
.pipe(changed(imgSrc))
|
||||
.pipe(imageMin()).on('error', onError)
|
||||
.pipe(gulp.dest(imgDst));
|
||||
});
|
||||
|
||||
gulp.task('uglify-js', function () {
|
||||
return gulp.src(distdir + '/js/*.js')
|
||||
.pipe(uglify()).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/js/'));
|
||||
});
|
||||
|
||||
gulp.task('minify-css', function() {
|
||||
return gulp.src(distdir + '/css/*.css')
|
||||
.pipe(minifyCSS({compatibility: 'ie8'})).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'));
|
||||
});
|
||||
|
||||
gulp.task('copy', function() {
|
||||
gulp.src(srcdir + '/fonts/**/*')
|
||||
.pipe(gulp.dest(distdir + '/fonts/'));
|
||||
gulp.src(srcdir + '/images/**/*')
|
||||
.pipe(gulp.dest(distdir + '/images/'));
|
||||
gulp.src(builddir + '/favicons/**/*')
|
||||
.pipe(gulp.dest(distdir + '/favicons/'));
|
||||
});
|
||||
|
||||
gulp.task('styles_fck', function() {
|
||||
gulp.src(srcdir + "/less/app/fck.less")
|
||||
.pipe(less()).on('error', onError)
|
||||
.pipe(minifyCSS({compatibility: 'ie8'})).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + "/css/"));
|
||||
});
|
||||
|
||||
gulp.task('bootstrap-less',function () {
|
||||
gulp.src(bowerdir + "/bootstrap/less/bootstrap.less")
|
||||
.pipe(less()).on('error', onError)
|
||||
.pipe(minifyCSS({compatibility: 'ie8'})).on('error', onError)
|
||||
.pipe(gulp.dest(builddir + "/css/"));
|
||||
})
|
||||
gulp.task('bootstrap-js',function () {
|
||||
gulp.src([
|
||||
bowerdir + '/bootstrap/js/affix.js',
|
||||
bowerdir + '/bootstrap/js/alert.js',
|
||||
bowerdir + '/bootstrap/js/button.js',
|
||||
//bowerdir + '/bootstrap/js/carousel.js',
|
||||
//bowerdir + '/bootstrap/js/collapse.js',
|
||||
//bowerdir + '/bootstrap/js/dropdown.js',
|
||||
bowerdir + '/bootstrap/js/modal.js',
|
||||
//bowerdir + '/bootstrap/js/popover.js',
|
||||
//bowerdir + '/bootstrap/js/scrollspy.js',
|
||||
//bowerdir + '/bootstrap/js/tab.js',
|
||||
bowerdir + '/bootstrap/js/tooltip.js',
|
||||
bowerdir + '/bootstrap/js/transition.js',
|
||||
bowerdir + '/jsvat/dist/jsvat.js'
|
||||
])
|
||||
.pipe(insert.append(';'))
|
||||
.pipe(concat('bootstrap.js'))
|
||||
.pipe(gulp.dest(builddir + '/js/'));
|
||||
})
|
||||
|
||||
gulp.task('watch', function () {
|
||||
gulp.watch(srcdir + '/less/**/*.less',['styles_dev']);
|
||||
gulp.watch(srcdir + '/less/**/**/*.less',['styles_dev']);
|
||||
gulp.watch(srcdir + '/js/**/*.js', ['scripts']);
|
||||
gulp.watch('./mysyde/**/*.js', ['scripts']);
|
||||
});
|
||||
|
||||
//B2B Catalog & Login
|
||||
if(shoptype == 2) {
|
||||
gulp.task('concat-js-b2b-components',function () {
|
||||
return gulp.src([
|
||||
bowerdir + '/jquery/jquery.min.js',
|
||||
builddir + '/js/bootstrap.js',
|
||||
bowerdir + '/jquery-hoverIntent/jquery.hoverIntent.js',
|
||||
bowerdir + '/seiyria-bootstrap-slider/dist/bootstrap-slider.min.js',
|
||||
bowerdir + '/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js',
|
||||
bowerdir + '/owl.carousel/dist/owl.carousel.min.js',
|
||||
bowerdir + '/magicscroll/magicscroll.js',
|
||||
bowerdir + '/magiczoomplus/magiczoomplus.js',
|
||||
bowerdir + '/password-strength-meter/dist/password.min.js',
|
||||
'./mysyde/common/cookie-bar/cookiebar-latest.js',
|
||||
'./mysyde/common/common.js',
|
||||
'./module/dcshop/common/dc_functions.js'
|
||||
])
|
||||
.pipe(concat('components_b2b.js'))
|
||||
.pipe(gulp.dest(builddir + '/js/'));
|
||||
})
|
||||
|
||||
gulp.task('concat-js-catalog-components',function () {
|
||||
return gulp.src([
|
||||
bowerdir + '/jquery/jquery.min.js',
|
||||
builddir + '/js/bootstrap.js',
|
||||
bowerdir + '/jquery-hoverIntent/jquery.hoverIntent.js',
|
||||
bowerdir + '/seiyria-bootstrap-slider/dist/bootstrap-slider.min.js',
|
||||
bowerdir + '/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js',
|
||||
bowerdir + '/owl.carousel/dist/owl.carousel.min.js',
|
||||
bowerdir + '/magicscroll/magicscroll.js',
|
||||
bowerdir + '/magiczoomplus/magiczoomplus.js',
|
||||
'./mysyde/common/common.js',
|
||||
'./module/dcshop/common/dc_functions.js'
|
||||
])
|
||||
.pipe(concat('components_catalog.js'))
|
||||
.pipe(gulp.dest(builddir + '/js/'));
|
||||
})
|
||||
|
||||
gulp.task('concat-css-components',function () {
|
||||
return gulp.src([
|
||||
bowerdir + '/normalize-css/normalize.css',
|
||||
bowerdir + '/font-awesome/css/font-awesome.min.css',
|
||||
bowerdir + '/material-design-icons/iconfont/material-icons.css',
|
||||
builddir + '/css/bootstrap.css',
|
||||
bowerdir + '/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
|
||||
bowerdir + '/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css',
|
||||
bowerdir + '/animate.css/animate.min.css',
|
||||
bowerdir + '/owl.carousel/dist/assets/owl.carousel.min.css',
|
||||
bowerdir + '/owl.carousel/dist/assets/owl.theme.default.min.css',
|
||||
bowerdir + '/password-strength-meter/dist/password.min.css',
|
||||
bowerdir + '/magicscroll/magicscroll.css',
|
||||
bowerdir + '/magiczoomplus/magiczoomplus.css'
|
||||
])
|
||||
.pipe(concat('components.css')).on('error', onError)
|
||||
.pipe(gulp.dest(builddir + '/css/'));
|
||||
})
|
||||
|
||||
gulp.task('styles_dev', function() {
|
||||
streamqueue({ objectMode: true},
|
||||
gulp.src(builddir + '/css/components.css')
|
||||
.pipe(gulp.dest(distdir + '/css/')),
|
||||
|
||||
gulp.src(srcdir + "/less/app/style_catalog.less")
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(less())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
.pipe(concat('style_catalog.css')).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/')),
|
||||
|
||||
gulp.src(srcdir + "/less/app/style_b2b.less")
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(less())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
.pipe(concat('style_b2b.css')).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/')),
|
||||
|
||||
gulp.src(srcdir + "/less/app/style_login.less")
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(less())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
.pipe(concat('style_login.css')).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
)
|
||||
});
|
||||
|
||||
gulp.task('styles_public_b2b', function() {
|
||||
streamqueue({ objectMode: true},
|
||||
gulp.src(builddir + '/css/components.css').on('error', onError),
|
||||
gulp.src(srcdir + "/less/app/style_b2b.less")
|
||||
.pipe(less())
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
)
|
||||
.pipe(concat('style_b2b.min.css')).on('error', onError)
|
||||
.pipe(minifyCSS({compatibility: 'ie8'})).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'));
|
||||
});
|
||||
|
||||
gulp.task('styles_public_catalog', function() {
|
||||
streamqueue({ objectMode: true},
|
||||
gulp.src(builddir + '/css/components.css').on('error', onError),
|
||||
gulp.src(srcdir + "/less/app/style_catalog.less")
|
||||
.pipe(less())
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
)
|
||||
.pipe(concat('style_catalog.min.css')).on('error', onError)
|
||||
.pipe(minifyCSS({compatibility: 'ie8'})).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'));
|
||||
});
|
||||
|
||||
gulp.task('styles_public_login', function() {
|
||||
streamqueue({ objectMode: true},
|
||||
gulp.src(builddir + '/css/components.css').on('error', onError),
|
||||
gulp.src(srcdir + "/less/app/style_login.less")
|
||||
.pipe(less())
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
)
|
||||
.pipe(concat('style_login.min.css')).on('error', onError)
|
||||
.pipe(minifyCSS({compatibility: 'ie8'})).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'));
|
||||
});
|
||||
|
||||
gulp.task('styles_public', function(callback) {
|
||||
runSequence(
|
||||
[
|
||||
'styles_public_b2b',
|
||||
'styles_public_catalog',
|
||||
'styles_public_login'
|
||||
],
|
||||
callback);
|
||||
});
|
||||
|
||||
gulp.task('scripts', function() {
|
||||
streamqueue({ objectMode: true},
|
||||
gulp.src([
|
||||
builddir + '/js/components_catalog.js',
|
||||
srcdir + '/js/script_catalog.js'
|
||||
])
|
||||
.pipe(concat('script_catalog.js'))
|
||||
.pipe(gulp.dest(distdir + '/js/')),
|
||||
|
||||
gulp.src([
|
||||
builddir + '/js/components_b2b.js',
|
||||
srcdir + '/js/script_b2b.js'
|
||||
])
|
||||
.pipe(concat('script_b2b.js'))
|
||||
.pipe(gulp.dest(distdir + '/js/')),
|
||||
|
||||
gulp.src([
|
||||
builddir + '/js/components_catalog.js',
|
||||
srcdir + '/js/script_login.js'
|
||||
])
|
||||
.pipe(concat('script_login.js'))
|
||||
.pipe(gulp.dest(distdir + '/js/'))
|
||||
)
|
||||
});
|
||||
|
||||
gulp.task('default', function(callback) {
|
||||
runSequence(
|
||||
'clean-dist',
|
||||
'bootstrap-less',
|
||||
'bootstrap-js',
|
||||
'concat-css-components',
|
||||
'concat-js-catalog-components',
|
||||
'concat-js-b2b-components',
|
||||
'generate-iconfont',
|
||||
'styles_dev',
|
||||
'scripts',
|
||||
'copy',
|
||||
'watch',
|
||||
callback);
|
||||
});
|
||||
|
||||
gulp.task('public', function(callback) {
|
||||
runSequence(
|
||||
'clean-dist',
|
||||
'bootstrap-less',
|
||||
'bootstrap-js',
|
||||
'concat-css-components',
|
||||
'concat-js-catalog-components',
|
||||
'concat-js-b2b-components',
|
||||
'generate-iconfont',
|
||||
'styles_public',
|
||||
'styles_fck',
|
||||
'scripts',
|
||||
'uglify-js',
|
||||
'copy',
|
||||
'minify-images',
|
||||
'generate-favicon',
|
||||
callback);
|
||||
});
|
||||
//B2C
|
||||
}else{
|
||||
gulp.task('concat-js-components',function () {
|
||||
return gulp.src([
|
||||
bowerdir + '/jquery/jquery.min.js',
|
||||
bowerdir + '/mediaelement/build/mediaelement-and-player.min.js',
|
||||
builddir + '/js/bootstrap.js',
|
||||
bowerdir + '/jquery-hoverIntent/jquery.hoverIntent.js',
|
||||
bowerdir + '/bxslider/jquery.bxslider-rahisified.min.js',
|
||||
bowerdir + '/seiyria-bootstrap-slider/dist/bootstrap-slider.min.js',
|
||||
bowerdir + '/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js',
|
||||
bowerdir + '/owl.carousel/dist/owl.carousel.min.js',
|
||||
bowerdir + '/magicscroll/magicscroll.js',
|
||||
bowerdir + '/magiczoomplus/magiczoomplus.js',
|
||||
bowerdir + '/password-strength-meter/dist/password.min.js',
|
||||
'./mysyde/common/cookie-bar/cookiebar-latest.js',
|
||||
'./mysyde/common/common.js',
|
||||
'./module/dcshop/common/dc_functions.js',
|
||||
'./plugins/jQuery-actual/jquery.actual.min.js'
|
||||
])
|
||||
.pipe(concat('components.js'))
|
||||
.pipe(gulp.dest(builddir + '/js/'));
|
||||
})
|
||||
|
||||
gulp.task('scripts',function () {
|
||||
return gulp.src([
|
||||
builddir + '/js/components.js',
|
||||
srcdir + '/js/script.js'
|
||||
])
|
||||
.pipe(concat('script.js'))
|
||||
.pipe(gulp.dest(distdir + '/js/'));
|
||||
})
|
||||
|
||||
gulp.task('concat-css-components',function () {
|
||||
return gulp.src([
|
||||
bowerdir + '/mediaelement/build/mediaelementplayer.min.css',
|
||||
bowerdir + '/normalize-css/normalize.css',
|
||||
bowerdir + '/font-awesome/css/font-awesome.min.css',
|
||||
bowerdir + '/material-design-icons/iconfont/material-icons.css',
|
||||
builddir + '/css/bootstrap.css',
|
||||
bowerdir + '/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
|
||||
bowerdir + '/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css',
|
||||
bowerdir + '/animate.css/animate.min.css',
|
||||
bowerdir + '/owl.carousel/dist/assets/owl.carousel.min.css',
|
||||
bowerdir + '/owl.carousel/dist/assets/owl.theme.default.min.css',
|
||||
bowerdir + '/magicscroll/magicscroll.css',
|
||||
bowerdir + '/password-strength-meter/dist/password.min.css',
|
||||
bowerdir + '/magiczoomplus/magiczoomplus.css'
|
||||
])
|
||||
.pipe(concat('components.css')).on('error', onError)
|
||||
.pipe(gulp.dest(builddir + '/css/'));
|
||||
})
|
||||
|
||||
gulp.task('styles_dev', function() {
|
||||
streamqueue({ objectMode: true},
|
||||
|
||||
gulp.src(builddir + '/css/components.css')
|
||||
.pipe(gulp.dest(distdir + '/css/')),
|
||||
|
||||
gulp.src(srcdir + "/less/app/style.less")
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(less())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
.pipe(concat('style.css')).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
)
|
||||
});
|
||||
|
||||
gulp.task('styles_public', function() {
|
||||
streamqueue({ objectMode: true},
|
||||
gulp.src(builddir + '/css/components.css').on('error', onError),
|
||||
gulp.src(srcdir + "/less/app/style.less")
|
||||
.pipe(less())
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
.on('error', onError)
|
||||
)
|
||||
.pipe(concat('style.min.css')).on('error', onError)
|
||||
.pipe(minifyCSS({compatibility: 'ie8'})).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'));
|
||||
});
|
||||
|
||||
gulp.task('autoprefixer',function () {
|
||||
gulp.src(distdir + '/css/style.css')
|
||||
.pipe(autoprefixer({
|
||||
browsers: ['last 2 versions'],
|
||||
cascade: false
|
||||
})).on('error', onError)
|
||||
.pipe(gulp.dest(distdir + '/css/'))
|
||||
});
|
||||
|
||||
gulp.task('default', function(callback) {
|
||||
runSequence(
|
||||
'clean-dist',
|
||||
'bootstrap-less',
|
||||
'bootstrap-js',
|
||||
'concat-css-components',
|
||||
'concat-js-components',
|
||||
'generate-iconfont',
|
||||
'styles_dev',
|
||||
'autoprefixer',
|
||||
'scripts',
|
||||
'copy',
|
||||
'watch',
|
||||
callback);
|
||||
});
|
||||
|
||||
gulp.task('public', function(callback) {
|
||||
runSequence(
|
||||
'clean-dist',
|
||||
'bootstrap-less',
|
||||
'bootstrap-js',
|
||||
'concat-css-components',
|
||||
'concat-js-components',
|
||||
'generate-iconfont',
|
||||
'styles_public',
|
||||
'styles_fck',
|
||||
'scripts',
|
||||
'autoprefixer',
|
||||
'uglify-js',
|
||||
'copy',
|
||||
'minify-images',
|
||||
'generate-favicon',
|
||||
callback);
|
||||
});
|
||||
}
|
||||
|
||||
function onError(err) {
|
||||
console.log(err);
|
||||
this.emit('end');
|
||||
}
|
||||
Reference in New Issue
Block a user