Greasy Fork

Greasy Fork is available in English.

bilibili关灯及快捷操作

bilibili关灯及快捷操作(把被新版B站藏起来的关灯按钮揪出来,在关闭弹幕按钮左边,还可以用快捷键,默认'A')、非全屏滚轮音量控制、弹幕控制快捷操作等

当前为 2022-03-15 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         bilibili关灯及快捷操作
// @namespace    hhh2000
// @version      0.9.6.1
// @description  bilibili关灯及快捷操作(把被新版B站藏起来的关灯按钮揪出来,在关闭弹幕按钮左边,还可以用快捷键,默认'A')、非全屏滚轮音量控制、弹幕控制快捷操作等
// @author       hhh2000
// @include      http*://www.bilibili.com/video/av*
// @include      http*://www.bilibili.com/video/BV*
// @include      http*://www.bilibili.com/watchlater/*
// @include      http*://www.bilibili.com/medialist/play/*
// @include      http*://www.bilibili.com/bangumi/play/ep*
// @include      http*://www.bilibili.com/bangumi/play/ss*
// @include      http*://bangumi.bilibili.com/anime/*/play*
// @include      http*://bangumi.bilibili.com/movie/*
// @include      http*://www.bilibili.com/blackboard/*
// @include      http*://t.bilibili.com/*
// @include      http*://space.bilibili.com/*
// @include      http*://www.bilibili.com/video/online.html*
// @require      https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
/* globals jQuery, $, waitForkeyElements */
/* eslint-disable no-multi-spaces, dot-notation */
// @run-at       document-end
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_listValues
// @grant        none
// ==/UserScript==

'use strict';
var hhh_lightoff_main = {
    init() {
        var //
            ver,
            fps,
            h5Player,
            curr_focus,
            is_in_biliplayer,
            is_show_hint,
            $tip,
            move_frames;
        //const [BILI_2_X_V2, BILI_3_X, ALL] = ['bili_2.x', 'bili_3.x', 'all'];
        const [BILI_2_X_V2, BILI_2_X_V3, BILI_2_X, BILI_3_X, ALL] = ['bili_2.x.v2', 'bili_2.x.v3', 'bili_2.x', 'bili_3.x', 'all'];
        var //切换番剧和一般视频class
            bb = {},
            bb_type = '',
            bb_config = {
                bb_class_data: {  //其实这样不方便调试
                    //'player':{BILI_2_X_V2:'.player', [BILI_3_X]:'.bpx-player'}, //main

                    //$('meta[property="og:image"]').attr('content')
                    'coverImg':{[ALL]:'meta[property="og:image"]'}, //封面

                    'playTipWrap':{[BILI_2_X]  :'.bilibili-player-dm-tip-wrap', [BILI_3_X]:'.bpx-player-video-perch'}, //paly/pause
                    'fullScreen':{[BILI_2_X]   :'.bilibili-player-video-btn-fullscreen', [BILI_3_X]:'.squirtle-video-fullscreen.squirtle-video-item'}, //全屏
                    'webFullScreen':{[BILI_2_X]:'.bilibili-player-video-web-fullscreen', [BILI_3_X]:'.squirtle-video-pagefullscreen.squirtle-video-item'}, //网页全屏
                    'wideScreen':{[BILI_2_X]   :'.bilibili-player-video-btn-widescreen', [BILI_3_X]:'.squirtle-video-widescreen.squirtle-video-item'}, //宽屏

                    //一健三联
                    'like'   :{[BILI_2_X_V2]:'.ops .like'   , [BILI_2_X_V3]:'.toolbar-left .like'   , [BILI_3_X]:'.like-info'}, //点赞
                    'likeon' :{[BILI_2_X_V2]:'.ops .like.on', [BILI_2_X_V3]:'.toolbar-left .like.on', [BILI_3_X]:'.like-info.active'}, //已点赞
                    'coin'   :{[BILI_2_X_V2]:'.ops .coin'   , [BILI_2_X_V3]:'.toolbar-left .coin'   , [BILI_3_X]:'.coin-info'}, //硬币
                    'collect':{[BILI_2_X_V2]:'.ops .collect', [BILI_2_X_V3]:'.toolbar-left .collect', [BILI_3_X]:''}, //收藏

                    //弹幕
                    'danmukuTopClose':{[BILI_2_X]:'.bilibili-player-block-filter-type[data-name=ctlbar_danmuku_top_close]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeTop.bpx-player-active'}, //顶部弹幕
                    'danmukuTop'     :{[BILI_2_X]:'.bilibili-player-block-filter-type[ftype=top]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeTop'}, //顶部弹幕
                    'danmukuBottomClose':{[BILI_2_X]:'.bilibili-player-block-filter-type[data-name=ctlbar_danmuku_bottom_close]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeBottom.bpx-player-active'}, //底部弹幕
                    'danmukuBottom'     :{[BILI_2_X]:'.bilibili-player-block-filter-type[ftype=bottom]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeBottom'}, //底部弹幕
                    'progressVal'   :{[ALL]:'.bui-progress-val'}, //弹幕透明度读数
                    'progressWrap'  :{[ALL]:'.bui-progress-wrap'}, //弹幕透明度进度条
                    'settingOpacity':{[BILI_2_X]:'.bilibili-player-setting-opacity', [BILI_3_X]:'.bpx-player-dm-setting-ui-opacity'}, //弹幕透明度
                    'settingFontsize':{[BILI_2_X]:'.bilibili-player-setting-fontsize', [BILI_3_X]:'.bpx-player-dm-setting-ui-fontsize'}, //弹幕字号
                    'settingArea'   :{[BILI_2_X]:'.bilibili-player-setting-area', [BILI_3_X]:'.bpx-player-dm-setting-ui-area'}, //显示区域
                    'settingFs'     :{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-fs input', [BILI_3_X]:'.bpx-player-dm-setting-left-fs input'}, //弹幕随屏幕缩放

                    //音量
                    'volumeHint'    :{[BILI_2_X]:'.bilibili-player-volumeHint', [BILI_3_X]:'.bpx-player-volume-hint'}, //音量显示
                    'volumeHintText':{[BILI_2_X]:'.bilibili-player-volumeHint-text', [BILI_3_X]:'.bpx-player-volume-hint-text'}, //音量显示百分比读数
                    'volumeHintIcon':{[BILI_2_X]:'.bilibili-player-volumeHint-icon', [BILI_3_X]:'.bpx-player-volume-hint-icon'}, //音量显示图标
                    'volumebarWrp'  :{[BILI_2_X]:'.bilibili-player-video-volumebar-wrp', [BILI_3_X]:'.squirtle-volume-bar-wrap'}, //音量条
                    'volumeNum'     :{[BILI_2_X]:'.bilibili-player-video-volume-num', [BILI_3_X]:'.squirtle-volume-num'}, //音量读数

                    //视频速度
                    'videoSpeedActive':{[BILI_2_X]:'.bilibili-player-video-btn-speed-menu-list.bilibili-player-active', [BILI_3_X]:'.squirtle-speed-select-list .squirtle-select-item.active'}, //视频速度
                    'videoSpeed':{[BILI_2_X]:'.bilibili-player-video-btn-speed-menu-list', [BILI_3_X]:'.squirtle-speed-select-list .squirtle-select-item'}, //视频速度
                    'videoSpeedName':{[BILI_2_X]:'.bilibili-player-video-btn-speed-name', [BILI_3_X]:'.squirtle-select-result.squirtle-speed-select-result'}, //视频速度

                    //弹幕设置等
                    'switchBody':{[ALL]:'.bui-switch-body'}, //系统关灯css设置
                    'switchDot':{[ALL]:'.bui-switch-dot'}, //系统弹幕设置按钮wrap进度条拖动点

                    'switchInput':{[BILI_2_X_V3]:'.bui-danmaku-switch-input', [ALL]:'.bui-switch-input'}, //弹幕设置switch按钮
                    'switchLabel':{[BILI_2_X_V3]:'.bui-danmaku-switch-label', [ALL]:'.bui-switch-label'}, //弹幕设置switchLabel

                    'danmaku':{[BILI_2_X]:'.bilibili-player-video-danmaku', [BILI_3_X]:'.bpx-player-row-dm-wrap'}, //弹幕
                    'danmakuRoot':{[BILI_2_X]:'.bilibili-player-video-danmaku-root', [BILI_3_X]:'.bpx-player-dm-root'}, //系统弹幕设置条
                    'danmakuSwitch':{[BILI_2_X]:'.bilibili-player-video-danmaku-switch', [BILI_3_X]:'.bpx-player-dm-switch'}, //关闭弹幕按钮

                    'dm':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting', [BILI_3_X]:'.bpx-player-dm-setting'}, //系统弹幕设置按钮
                    'dmWrap':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-wrap', [BILI_3_X]:'.bpx-player-dm-setting-wrap'}, //系统弹幕设置wrap
                    'dmBox':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-box', [BILI_3_X]:'.bpx-player-dm-setting-box'}, //系统弹幕设置box
                    'dmLeft':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left', [BILI_3_X]:'.bpx-player-dm-setting-left'},
                    'dmLeftMore':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-more', [BILI_3_X]:'.bpx-player-dm-setting-left-more'},
                    'dmLeftMoreText':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-more-text', [BILI_3_X]:'.bpx-player-dm-setting-left-more-text'},
                    'dmLeftBlock':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-block', [BILI_3_X]:'.bpx-player-dm-setting-left-block'},
                    'dmLeftBlockTitle':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-block-title', [BILI_3_X]:'.bpx-player-dm-setting-left-block-title'},
                    'dmRightMore':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-more', [BILI_3_X]:'.bpx-player-dm-setting-right-more'},
                    'dmRightMoreText':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-more-text', [BILI_3_X]:'.bpx-player-dm-setting-right-more-text'},
                    'dmRightSeparator':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-separator', [BILI_3_X]:'.bpx-player-dm-setting-right-separator'},
                    'dmRightDensity':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-density', [BILI_3_X]:'.bpx-player-dm-setting-right-density'},
                    'dmRightReset':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-reset', [BILI_3_X]:'.bpx-player-dm-setting-right-reset'},

                    'videoWrap':{[BILI_2_X]:'.bilibili-player-video-wrap', [BILI_3_X]:'.bpx-player-video-area'}, //播放wrap
                    'videoContextMenu':{[BILI_2_X]:'.bilibili-player-video-wrap', [BILI_3_X]:'.bpx-player-video-perch'}, //播放contextmenu
                    'video':{[BILI_2_X]:'.bilibili-player-video', [BILI_3_X]:'.bpx-player-video-wrap'}, //播放
                    'videoTopMask':{[BILI_2_X]:'.bilibili-player-video-top-mask', [BILI_3_X]:'.bpx-player-top-mask'}, //全屏时鼠标悬停时产生的顶端mask

                    //系统设置等
                    'playArea':{[ALL]:'.bilibili-player-area'}, //哔哩哔哩播放器
                    'playVideo':{[BILI_2_X]:'.bilibili-player-video-btn'}, //系统设置
                    'playVideoControlWrap':{[BILI_2_X]:'.bilibili-player-video-control-wrap', [BILI_3_X]:'.bpx-player-control-wrap'}, //系统控制面板
                    'playSetting':{[BILI_2_X]:'.bilibili-player-video-btn-setting'}, //系统播放设置
                    'playSettingWrap':{[BILI_2_X]:'.bilibili-player-video-btn-setting-wrap'}, //系统播放设置wrap
                    'playSettingAutoplay':{[BILI_2_X]:'.bilibili-player-video-btn-setting-left-autoplay input', [BILI_3_X]: '.squirtle-setting-autoplay'}, //自动播放
                    'playSettingRepeatInput':{[BILI_2_X]:'.bilibili-player-video-btn-setting-left-repeat input', [BILI_3_X]:'.squirtle-setting-loop'}, //洗脑循环按钮
                    'playSettingLightoff':{[BILI_2_X]:'.bilibili-player-video-btn-setting-right-others-content-lightoff input', [BILI_3_X]:'.squirtle-single-setting-other-choice.squirtle-lightoff'}, //关灯按钮
                    'bpxStateLightOff':{[BILI_3_X]:'.bpx-state-light-off'}, //关灯bpx
                    'playJumpElectric':{[BILI_2_X]:'.bilibili-player-electric-panel-jump'}, //2.69.4版本B站取消充电鸣谢,2.72又加回来了

                    //右键菜单
                    'playerContextMenu':{[BILI_2_X]:'.bilibili-player-context-menu-container.black.bilibili-player-context-menu-origin', [BILI_3_X]:'.bpx-player-contextmenu.bpx-player-black'}, //右键菜单
                    'hotkeyPanel':{[BILI_2_X]:'.bilibili-player-hotkey-panel-container', [BILI_3_X]:'.bpx-player-hotkey-panel'}, //快捷键说明面板
                    'hotkeyPanelClose':{[BILI_2_X]:'.bilibili-player-hotkey-panel-close', [BILI_3_X]:'.bpx-player-hotkey-panel-close'}, //快捷键说明面板关闭按钮
                    'videoInfo':{[BILI_2_X]:'.bilibili-player-video-info', [BILI_3_X]:'.bpx-player-info'}, //视频统计信息
                    'videoInfoClose':{[BILI_2_X]:'.bilibili-player-video-info-close', [BILI_3_X]:'.bpx-player-info-close'}, //视频统计信息关闭按钮
                    'videoInfoContainer':{[BILI_2_X]:'.bilibili-player-video-info-container', [BILI_3_X]:'.bpx-player-info-container'}, //视频统计信息
                    'videoInfoShow':{[BILI_2_X]:'.bilibili-player-video-info-container active', [BILI_3_X]:'.bpx-player-info-container'}, //视频统计信息面板显示
                    'DOMNodeInsertedVideoInfoShow':{[BILI_2_X]:'.bilibili-player-video-info-container active', [BILI_3_X]:'.info-line'}, //
                },
                set_bb(_bb_type) {
                    bb_type = _bb_type;
                    for(var k in this.bb_class_data){
                        var class_str = this.bb_class_data[k][bb_type] || this.bb_class_data[k][[BILI_2_X]] || this.bb_class_data[k][[ALL]];
                        bb[k] = class_str;
                    }
                }
           };

        const [ON, OFF] = [true, false];
        var //config
            keycode = {
                'Enter': 13,
                'Ctrl': 17,
                'Esc': 27,
                'left': 37,
                'right': 39,
                'up': 38,
                'down': 40,
                'space': 32,
                '/': 191,
            },
            config = {
                //一些主要开关设置
                sets: {},
                getCheckboxSettingStatus(key) {
                    return this.sets[key]['status'];
                },
                getCheckboxSettingFn(key) {
                    return this.sets[key]['fn'];
                },
                getCheckboxSettingArgs(key) {
                    return this.sets[key]['args'];
                },
                setCheckboxSettingStatus(key, status) {
                    this.sets[key]['status'] = status;
                },
                setCheckboxSettingTips(key, tips) {
                    this.sets[key]['tips'] = tips;
                },
                saveCheckboxSetting() {
                    for(var o in this){
                        if(o.indexOf('b_') === 0){
                            this.sets = JSON.parse(JSON.stringify(this[o]['options']));
                        }
                    }
                },
                b_playerCheckbox: {
                    options: {
                        autoPlay: { text: '自动播放', status: OFF, tips: '' },
                        lightOff: { text: '自动关灯', status: OFF, tips: '' },
                        autoFullScreen: { text: '自动全屏', status: OFF, tips: '' },
                        autoWebFullScreen: { text: '自动网页全屏', status: OFF, tips: '' },
                        videoRepeat: { text: '自动洗脑循环', status: OFF, tips: '' },
                        lightOffWhenPlaying: { text: '播放时自动关灯', status: OFF, fn: 'lightOffWhenPlaying' },
                        lightOnWhenPause: { text: '暂停时自动开灯', status: OFF, fn: 'lightOnWhenPause' },
                        rememberVideoRepeat: { text: '记忆洗脑循环', status: ON, tips: '优先级低于【自动洗脑循环】', show: OFF }, //优先级低于videoRepeat
                        dblclickFullScreen: { text: '双击或中键全屏', status: ON, tips: '', fn: 'dblclickFullScreen' },
                        volumeControlWhenNonFullScreen: { text: '非全屏滚轮音量调节', status: ON, tips: '', fn: 'wheel_volumeHint', args:{screenLeft: 0.3, screenRight: 0.7, delta: 1} },
                        volumeControlWhenPause: { text: '非全屏暂停时滚轮音量调节', status: ON, tips: '' },
                        danmuOpacityControl: { text: '滚轮弹幕透明度控制', status: ON, tips: 'Ctrl + 滚轮', fn: 'wheel_opacity', args:{delta: 5} }, //ctrl+滚轮
                        keyVideoSpeed: { text: '键盘调节视频速度', status: ON, tips: 'Ctrl + ↑↓' },
                        removeVideoTopMask: { text: '去掉顶部mask', status: ON, tips: '', fn: 'removeVideoTopMask' },
                        jumpElectric: { text: '跳过充电鸣谢', status: ON, fn: 'jumpElectric' }, //2.69.4版本B站取消充电鸣谢,2.72又加回来了
                        reloadDanmuku: { text: '快进快退恢复重载弹幕效果', status: OFF }, //快进快退恢复重载弹幕效果
                        //removeMostViewedListener: { text: '删除动态首页UP主动态提示', status: ON },
                        //不显示有明显变化的提示,关灯、关弹幕等,因为对有些人来说这些操作变化明显可见,提示反而多余且遮挡屏幕
                        hotKeyHint: { text: '快捷键屏幕提示', status: OFF, tips: '不显示有明显变化的提示,关灯、关弹幕等' },
                        openHotKey: { text: '开启自定义快捷键', status: ON, tips: '', 'fn': 'set_hotkey' },
                    },
                    btn: '设置'
                },
                //快捷键
                QDs: {}, //未使用
                getQD(key) {
                    return this.QDs[key];
                }, //未使用
                saveQD() {
                    for (let [key, { value, text }] of Object.entries(this.hotKeyMenu)) {
                        this.QDs[key] = {value: value, keyCode: value.charCodeAt(), text: text};
                    }
                }, //未使用
                hotKeyMenu: {  //只是右键菜单的数据,如需改动快捷键改run函数
                    'volumeControl': { value: '滚轮', text: '音量调节', },
                    'lightOff': { value: 'A', text: '关灯/开灯', },
                    'webFullscreen': { value: 'W', text: '网页全屏', },
                    'widescreen': { value: 'Q', text: '宽屏模式', },
                    'danmu': { value: 'D', text: '弹幕/关闭弹幕', },
                    'danmuTopBottom': { value: 'T/B', text: '顶部/底部弹幕', },
                    'videoRepeat': { value: 'R', text: '洗脑循环', },
                    'addsubDanmuOpacity': { value: 'Z/C', text: '减增弹幕透明度10%', },
                    'addsubDanmuFontsize': { value: 'V/N', text: '减增弹幕字号5%', },
                    'danmuArea': { value: '1、2、3、4、5', text: '弹幕显示区域 1/4屏~不限', },
                    // 'quarterArea': { value: '1', text: '1/4屏', },
                    // 'halfArea': { value: '2', text: '半屏', },
                    // 'threeQuarterArea': { value: '3', text: '3/4屏', },
                    // 'nonOverArea': { value: '4', text: '不重叠', },
                    // 'fullArea': { value: '5', text: '不限', },
                    'wheelDanmuOpacity': { value: 'Ctrl + 滚轮', text: '增减弹幕透明度5%', },
                    'fastForwardBackward30s': { value: 'Ctrl + ←/→', text: '快进/快退30s', },
                    '1/FPS': { value: 'Shift + ←/→', text: '逐帧操作', },
                    'keyVideoSpeed': { value: 'Ctrl + ↑/↓', text: '调节视频播放速度', },
                    'dblclickFullScreen': { value: '双击/中键/功能键', text: '全屏', },
                    'ctrl_enterFullScreen': { value: 'Ctrl+Enter', text: '全屏', },
                    'danmuZoomWithScreen': { value: 'S', text: '弹幕是否随屏幕缩放', },
                    'like': { value: 'Y、U、I、O', text: '点赞、投币、收藏、长按一键三连', },
                    'loop': { value: 'Ctrl + 左键 / L', text: '设定段落循环 / 设定后切换', },
                },
            };
        const assert = function(condition, message) {
            if (!condition)
                throw Error('Assert failed: ' + (message || 'Assertion failed'));
        }
        function log(e) {console.log(e)}
        function dir(e) {console.dir(e)}
        function set_value(key, value){ localStorage.setItem(key, value) }
        function get_value(key, default_value){ return localStorage.getItem(key) || default_value }

        function waitForNode(nodeSelector, callback, times) {
            //log('----n---');
            if(times < 0) return;
            var node = nodeSelector();
            if (node) {
                callback(node);
            } else {
                times-=1;
                setTimeout(function() { waitForNode(nodeSelector, callback, times); }, 50);
            }
        }
        function waitForTrue(ifTrue, callback) {
            //log('----t---');
            if (ifTrue()) {
                callback();
            } else {
                setTimeout(function() { waitForTrue(ifTrue, callback); }, 50);
            }
        }
        function is_fullscreen() {
            //if(bb_type.indexOf(BILI_2_X) !== -1){ return bili_player.isFullScreen() }
            if(bb_type.indexOf(BILI_2_X) !== -1){ return $('#bilibiliPlayer').hasClass('mode-webfullscreen') || $('#bilibiliPlayer').hasClass('mode-fullscreen')  }
            else if(bb_type === BILI_3_X){ return $('.bpx-player-container').attr('data-screen') === 'web' || $('.bpx-player-container').attr('data-screen') === 'full' }  //normal wide web full
        }
        function fullscreen() { $(bb['fullScreen']).click() }
        function web_fullscreen() { $(bb['webFullScreen']).click() }
        function wide_screen() { $(bb['wideScreen']).click() }
        function is_lightoff() {
            //if (bb_type.indexOf(BILI_2_X) !== -1) { return !bili_player.getPlayerState().lightOn }
            if (bb_type.indexOf(BILI_2_X) !== -1) { return $('#bilibiliPlayer').hasClass('mode-light-off') }
            else if(bb_type === BILI_3_X) { return $(bb['playSettingLightoff']).hasClass('active') }
        }
        function is_danmaku_show(){
            return $(bb['danmakuSwitch']+' '+bb['switchInput']+':last')[0].checked;
        }
        function lightoff() {
            $(bb['playSettingLightoff']).click()
        }
        function add_tip($tip, $node, args){
            $node.mouseover(function(){
                var e = this;
                var op = {};
                let t = setTimeout(function() {
                    $tip.appendTo(e);
                    let $this = $(e);
                    let $new_tip = $('.player-tooltips.tip.top-center.animation').css({top:0,left:0});

                    true === !!$this.data('tip') ? $.extend(true, op, $this.data('tip')) : $.extend(true, op, args);
                    $new_tip.find('.tooltip').text(op['text']);

                    let tip_new_top = $this.offset().top - $new_tip.offset().top - $new_tip.height();
                    //console.log('top:'+$this.offset().top+' tiptop: '+$new_tip.offset().top +' height: '+ $new_tip.height());
                    //console.log('left:'+$this.offset().left+' tipleft: '+$new_tip.offset().left +' width: '+ $this.width()+' tipwidth: '+ $new_tip.width());
                    //console.log('top:'+$this.css('top')+'left:'+$this.css('left'))
                    let tip_new_left = $this.offset().left - $new_tip.offset().left + ($this.width() - $new_tip.width())/2;
                    //console.log(tip_new_top+'  '+tip_new_left);
                    tip_new_left = tip_new_left <= 0 ? 0 : tip_new_left;
                    let diff_full_top = is_fullscreen() ? (op['diff_full_top'] || 0) : 0; //全屏时位置不同
                    $new_tip.css({'top':tip_new_top + op['top'] + diff_full_top, 'left':tip_new_left + op['left']}).addClass('active');
                }, op['millisec']);
                $(this).data('timeout', t);
            }).
            mouseout(function(e){
                clearTimeout($(this).data('timeout'));
                $('.player-tooltips.tip.top-center.animation').removeClass('active');
                $('.player-tooltips.tip.top-center.animation').remove();
            })
        }
        //关灯按钮样式
        function lightoff_btn_css() {
            var body_brgb = 'rgb(160, 130, 110)';
            var dot_crgb = 'rgb(230, 200, 180)';
            var dot_brgb = 'rgb(50, 50, 50)';
            var dark_rgb = 'rgb(77, 77, 77)';
            if ($('#hhh_lightoff '+bb['switchInput'])[0].checked === false) {  //关灯
                $('#hhh_lightoff '+bb['switchBody']+':first').css('background-color', dark_rgb);
                $('#hhh_lightoff '+bb['switchBody']+':first>'+bb['switchDot']).css('color', dark_rgb);
                $(`#hhh_lightoff ${bb['switchLabel']}`).removeClass('checked');
            }
            else {
                $('#hhh_lightoff '+bb['switchBody']+':first').css('background-color', body_brgb);
                $('#hhh_lightoff '+bb['switchBody']+':first>'+bb['switchDot']).css({'color': dot_crgb, 'background-color': dot_brgb});
                $(`#hhh_lightoff ${bb['switchLabel']}`).addClass('checked');
            }
        }
        //关灯按钮
        function lightoff_btn() {
            lightoff();
            let $light_input = $('#hhh_lightoff '+bb['switchInput']);
            if(is_lightoff() === $light_input[0].checked) {  //checked==true开灯 false关灯
                $light_input[0].checked = !$light_input[0].checked;
            }
            lightoff_btn_css();

            let light_tip_text = $light_input[0].checked === true? '关灯': '开灯';
            $('#hhh_lightoff .tooltip').text(light_tip_text);
            if(bb_type.indexOf(BILI_2_X) !== -1) $('#hhh_lightoff').data('tip')['text'] = light_tip_text;
        }
        //关灯按钮初始化
        function lightoff_init() {
            //插入关灯按钮
            $(`${bb['danmakuSwitch']}:first`).clone().prependTo(`${bb['danmakuRoot']}:first`)[0].id = 'hhh_lightoff';
            $('#hhh_lightoff '+bb['switchInput'])[0].checked = true;
            if(bb_type !== BILI_2_X_V3) $(`#hhh_lightoff ${bb['switchDot']}`)[0].innerHTML = '灯';
            else{
                //开灯
                $('#hhh_lightoff').find('.bui-danmaku-switch-on svg').replaceWith(`
                    <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path style="clip-rule:evenodd;fill-rule:evenodd" d="M 15.765 1.814 C 15.513 1.840 15.264 1.971 15.068 2.244 L 13.207 4.835 C 12.827 4.831 12.463 4.828 12.119 4.828 L 11.988 4.828 C 11.518 4.828 11.014 4.831 10.474 4.839 L 8.763 2.273 C 8.018 1.154 6.340 2.273 7.085
                    3.392 L 8.085 4.892 C 7.404 4.910 6.682 4.932 5.921 4.960 C 3.981 5.029 2.367 6.478 2.091 8.400 C 1.926 9.550 1.845 10.945 1.845 12.585 C 1.845 14.550 1.960 16.255 2.195 17.701 C 2.499 19.569 4.068 20.971 5.958 21.064 L 6.865 21.109 C 8.070 21.172 8.673 21.205 10.472
                    21.205 C 11.748 21.164 11.748 19.271 10.472 19.230 C 8.714 19.230 8.132 19.200 6.970 19.138 L 6.056 19.091 C 5.096 19.044 4.300 18.331 4.146 17.382 C 3.930 16.058 3.820 14.459 3.820 12.585 C 3.820 11.022 3.897 9.721 4.046 8.681 C 4.186 7.704 5.005 6.967 5.990 6.933 C
                    8.434 6.846 10.456 6.803 12.054 6.802 C 13.652 6.802 15.673 6.847 18.117 6.933 C 19.077 6.967 19.827 7.742 19.972 8.746 C 20.047 9.270 20.085 10.709 20.113 11.812 L 20.113 11.814 C 20.123 12.156 20.130 12.463 20.138 12.693 C 20.184 14.009 22.158 13.942 22.113 12.626 C
                    22.105 12.400 22.096 12.102 22.087 11.769 L 22.087 11.742 C 22.057 10.624 22.014 9.079 21.927 8.466 C 21.654 6.560 20.144 5.029 18.187 4.960 C 17.287 4.928 16.444 4.902 15.656 4.882 L 16.707 3.421 C 17.295 2.602 16.520 1.735 15.765 1.814 z M 8.896 8.152 C 8.896 9.808
                    8.883 10.962 8.855 11.613 C 8.831 12.260 8.747 12.892 8.605 13.513 C 8.466 14.134 8.271 14.693 8.017 15.189 C 7.764 15.682 7.456 16.112 7.095 16.480 C 7.359 16.756 7.695 17.191 8.105 17.783 C 8.838 16.784 9.358 15.814 9.667 14.871 C 10.122 15.390 10.560 15.912 10.980
                    16.441 L 12.052 15.396 C 11.413 14.729 10.733 14.076 10.011 13.439 C 10.067 13.104 10.114 12.726 10.152 12.302 C 10.850 11.691 11.511 11.083 12.136 10.478 L 11.126 9.562 C 10.911 9.845 10.622 10.200 10.261 10.630 C 10.289 9.891 10.302 9.065 10.302 8.152 L 8.896 8.152 z
                    M 11.751 8.625 L 11.751 9.947 L 14.052 9.947 L 14.052 15.357 C 14.052 15.915 13.792 16.195 13.271 16.195 C 12.872 16.195 12.387 16.176 11.814 16.136 C 11.971 16.575 12.099 17.059 12.203 17.585 A 1.939 1.750 0 0 1 13.539 17.101 A 1.939 1.750 0 0 1 14.625 17.402 C 14.708
                    17.370 14.808 17.345 14.871 17.304 C 15.103 17.160 15.277 16.953 15.392 16.683 C 15.507 16.414 15.564 16.082 15.564 15.691 L 15.564 9.947 L 17.458 9.947 L 17.458 8.625 L 11.751 8.625 z M 8.189 9.730 L 7.074 9.917 C 7.247 10.877 7.404 11.926 7.542 13.070 L 8.677 12.865 C 8.511 11.669 8.349 10.624 8.189 9.730 z "/>
                    <path fill-rule="evenodd" clip-rule="evenodd" d="M22.846 14.627a1 1 0 00-1.412.075l-5.091 5.703-2.216-2.275-.097-.086-.008-.005a1 1 0 00-1.322 1.493l2.963 3.041.093.083.007.005c.407.315 1 .27 1.354-.124l5.81-6.505.08-.102.005-.008a1 1 0 00-.166-1.295z" fill="#00AEEC"/>
                    </svg>`
                 );
                //关灯
                $('#hhh_lightoff').find('.bui-danmaku-switch-off svg').replaceWith(`
                    <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path style="clip-rule:evenodd;fill-rule:evenodd" d="M 15.765 1.814 C 15.514 1.840 15.264 1.971 15.068 2.244 L 13.207 4.835 C 12.826 4.831 12.464 4.828 12.119 4.828 L 11.988 4.828 C 11.518 4.828 11.014 4.831 10.474 4.839 L 8.765 2.273 C 8.020 1.154 6.340 2.273 7.085
                    3.392 L 8.085 4.890 L 8.083 4.890 C 7.402 4.909 6.680 4.933 5.919 4.960 C 3.979 5.030 2.367 6.478 2.091 8.400 C 1.926 9.549 1.845 10.943 1.845 12.583 C 1.845 14.548 1.961 16.253 2.197 17.699 C 2.500 19.567 4.068 20.970 5.958 21.064 C 7.861 21.158 9.276 21.205 11.472
                    21.205 C 12.748 21.164 12.748 19.271 11.472 19.230 C 9.666 19.234 7.860 19.188 6.056 19.091 C 5.096 19.043 4.300 18.331 4.146 17.382 C 3.931 16.058 3.820 14.459 3.820 12.585 C 3.820 11.022 3.896 9.721 4.046 8.681 C 4.186 7.704 5.004 6.968 5.990 6.933 C 8.434 6.847
                    10.456 6.802 12.054 6.802 C 13.652 6.803 15.673 6.846 18.117 6.933 C 19.076 6.966 19.829 7.742 19.972 8.746 C 20.048 9.270 20.085 10.709 20.113 11.812 L 20.113 11.814 C 20.122 12.156 20.130 12.465 20.138 12.695 C 20.184 14.011 22.159 13.942 22.113 12.626 C 22.105
                    12.400 22.097 12.102 22.087 11.769 L 22.087 11.742 C 22.057 10.624 22.015 9.079 21.927 8.466 C 21.655 6.559 20.145 5.029 18.187 4.960 C 17.288 4.928 16.444 4.902 15.656 4.882 L 16.705 3.421 C 17.293 2.603 16.520 1.736 15.765 1.814 z M 8.896 8.152 C 8.896 9.808 8.883
                    10.960 8.855 11.611 C 8.831 12.258 8.747 12.892 8.605 13.513 C 8.466 14.134 8.271 14.693 8.017 15.189 C 7.764 15.682 7.456 16.112 7.095 16.480 C 7.359 16.756 7.695 17.189 8.105 17.781 C 8.838 16.782 9.358 15.812 9.667 14.869 C 10.122 15.388 10.560 15.912 10.980 16.441
                    L 12.052 15.396 C 11.413 14.729 10.733 14.076 10.011 13.439 C 10.067 13.104 10.114 12.724 10.152 12.300 C 10.850 11.689 11.511 11.083 12.136 10.478 L 11.125 9.560 C 10.909 9.843 10.622 10.200 10.261 10.630 C 10.289 9.891 10.302 9.065 10.302 8.152 L 8.896 8.152 z
                    M 11.75 8.625 L 11.75 9.945 L 14.052 9.945 L 14.052 14.726 A 5.249 5.249 0 0 1 15.562 13.486 L 15.562 9.945 L 17.458 9.945 L 17.458 8.625 L 11.75 8.625 z M 8.189 9.728 L 7.074 9.916 C 7.247 10.875 7.404 11.926 7.542 13.070 L 8.677 12.863 C 8.511 11.667 8.349 10.622 8.189 9.728 z
                    M 18.062 14.062 C 12.729 14.062 12.729 22.062 18.062 22.062 C 23.395 22.062 23.395 14.062 18.062 14.062 z M 18.212 15.560 C 19.463 15.638 20.561 16.667 20.560 18.060 C 20.560 18.480 20.456 18.875 20.273 19.222 L 16.945 15.820 C 17.360 15.613 17.796 15.534 18.212 15.560 z
                    M 11.812 16.136 C 11.972 16.583 12.104 17.076 12.208 17.615 C 12.430 17.617 12.643 17.601 12.861 17.597 A 5.249 5.249 0 0 1 13.195 16.191 C 12.808 16.189 12.355 16.174 11.812 16.136 z M 15.843 16.902 L 19.169 20.300 C 18.825 20.471 18.445 20.561 18.060 20.560 C 16.182 20.561 14.974 18.567 15.843 16.902 z"/>
                    </svg>`
                 );
            }
            //css
            lightoff_btn_css();
            //add tips
            waitForTrue(()=> ($tip !== undefined && $('#hhh_lightoff').length === 1), () => {
                if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"flex"});
                $(bb['dmWrap']).css({"display":"block"});

                if(bb_type === BILI_2_X_V2) $('#hhh_lightoff').data('tip', {'text': '关灯', 'millisec':1, 'top':2, 'left':0, 'diff_full_top':-20});
                else if(bb_type === BILI_2_X_V3) $('#hhh_lightoff').data('tip', {'text': '关灯', 'millisec':1, 'top':-4, 'left':0, 'diff_full_top':-14});
                add_tip($tip, $('#hhh_lightoff'), {});

                $(bb['dmWrap']).css({"display":"none"});
                if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"none"});
            })
        }

        //模拟B站音量调节
        //2.X版本可以直接调用系统函数window.player.volume(),但不能直接使用H5Player.volume
        //3.X版本去掉了window.player.volume(),但H5Player.volume功能发生变动,基本等价于window.player.volume()
        function volume(v, is_show_hint=true){
            function volume_bar(v){  //未使用
                if(v === undefined) return;
                v = v<0? 0: v>1? 1: v;
                $('.bilibili-player-video-volume-num').text(Math.round(v*100));
                $('.bilibili-player-video-volumebar-wrp .bui-bar.bui-bar-normal')[0].style.transform = `scaleY(${v})`;
                $('.bilibili-player-video-volumebar-wrp .bui-thumb')[0].style.transform = `translateY(${-48*v}px)`;
                v === 0? $('.bilibili-player-video-btn.bilibili-player-video-btn-volume').addClass('video-state-volume-min'): $('.bilibili-player-video-btn.bilibili-player-video-btn-volume').removeClass('video-state-volume-min')
            }
            function volume_hint_bar(v){
                if(v === undefined) return;
                assert(typeof v === "number", '| volume err: v is not number')  //debug
                //v = v<0? 0: v>1? 1: v;
                v = +Math.max(Math.min(v,1),0).toFixed(3);
                var $volumeHintIcon = $(`#hhh_volumeHint ${bb['volumeHintIcon']}`);
                var volumeHintIconClassName = bb['volumeHintIcon'].substr(1);

                if(bb_type.indexOf(BILI_2_X) !== -1){
                    if(v <= 0) $volumeHintIcon.attr('class', `${volumeHintIconClassName} video-state-volume-min`);
                    else if(v >= 1) $volumeHintIcon.attr('class', `${volumeHintIconClassName} video-state-volume-max`);
                    else $volumeHintIcon.attr('class', volumeHintIconClassName);
                } else{
                    if(v <= 0){
                        $volumeHintIcon.find('.bpx-common-svg-icon:last').css('display','block');
                        $volumeHintIcon.find('.bpx-common-svg-icon:first').css('display','none');
                    } else{
                        $volumeHintIcon.find('.bpx-common-svg-icon:last').css('display','none');
                        $volumeHintIcon.find('.bpx-common-svg-icon:first').css('display','block');
                    }
                }

                if(v <= 0) showHint(this, '#hhh_volumeHint', '静音');
                else showHint(this, '#hhh_volumeHint', Math.round(v*100)+'%');
            }

            h5Player = ($(`${bb['video']} video`)[0] || $(`${bb['video']} bwp-video`)[0]);  // bug:调节清晰度会影响 h5Player 和window.player,需要重新赋值
            assert(typeof h5Player.volume === "number", '| volume err: h5Player.volume is not number')  //debug
            if(v === undefined) { /*log('v: '+h5Player.volume);*/ return +h5Player.volume;}
            v = +Math.max(Math.min(v,1),0).toFixed(3);
            assert(typeof v === "number", '| volume err: v is not number')  //debug
            //log('volume: '+v+'  '+h5Player);
            //v = v<0.01? 0: v>1? 1: v;  //0.01防止误差
            bb_type.indexOf(BILI_2_X) !== -1? window.player.volume(v): h5Player.volume = v;
            //h5Player.volume = v;
            if(is_show_hint === true) volume_hint_bar(+h5Player.volume);
            return +h5Player.volume;
        }

        //显示提示
        function showHint(parent, selector_str, text){
            $(bb['volumeHint']).css({"visibility":"visible"})
            $(bb['volumeHint']).css('display', 'none');  //隐藏所有提示,避免提示重叠
            $(`${selector_str}>${bb['volumeHintText']}`).text(text);  //百分比显示
            var Hint = $(selector_str);  //显示及渐隐效果(抄bilibili^^)
            clearTimeout(parent.showHintTimer),
                Hint.stop().css("opacity", 1).show(),
                parent.showHintTimer = window.setTimeout((function() {
                Hint.animate({
                    opacity: 0
                }, 300, (function() {
                    $(this).hide()
                }))
            }
            ), 1e3)
        }

        //非全屏滚轮音量调节 0~1 (b站默认滚轮操作某些情况会失效,一并处理全屏情况)
        //两个参数指定屏幕范围(按百分比),第三个参数表示滚动一下增加的音量百分比,参数四表示暂停时是否调节
        function wheel_volumeHint(isWheelVolume=ON, screenLeft=0.3, screenRight=0.7, delta=1, isPauseVolume=ON){
            $(bb['videoWrap']).off('mousewheel.hhh_volumeHint');
            if(!isWheelVolume) return;
            $(bb['videoWrap']).on('mousewheel.hhh_volumeHint', function(e){
                if(e.ctrlKey || e.altKey || e.shiftKey) return;
                //缺省屏幕百分比参数,默认0.3~0.7
                screenLeft = (screenLeft<0 || screenLeft>1)? 0.3: screenLeft;
                screenRight = (screenRight<0 || screenRight>1)? 0.7: screenRight;
                //缺省音量百分比,默认1
                delta = (delta<1 || delta>100)? 1: delta;

                //非暂停(可选) && 鼠标在屏幕指定位置时处理
                var pauseState = isPauseVolume || h5Player.paused === false;
                var Rect = $(bb['videoWrap'])[0].getBoundingClientRect();
                var offsetX = e.originalEvent.x - Rect.x;
                var inLimit = offsetX > Rect.width*screenLeft && offsetX < Rect.width*screenRight;

                if(is_fullscreen() || (pauseState && inLimit)) {
                    //阻止页面滚动 && 阻止冒泡
                    e.preventDefault();
                    e.stopPropagation();
                    var wheelDelta = e.originalEvent.wheelDelta;
                    var v = volume();
                    if(wheelDelta >= 120) {  //向上滚动,减少音量
                        volume(+(v+(delta/100)).toFixed(3));  //+ string to number
                    } else if(wheelDelta <= -120) {  //向下滚动,增大音量
                        volume(+(v-(delta/100)).toFixed(3));
                    }
                }
            });
        }

        /*
         * 控制进度条
         * .bilibili-player-setting-opacity 透明度
         * .bilibili-player-setting-area 显示区域
         * .bilibili-player-setting-speedplus 弹幕速度 等
         * 利用系统mousedown事件
         * 0 ~ 100
         */
        function set_progress(selector_str, percent, limit_left, limit_right){
            function calc_bar_offset2(percent, bar_width, limit_left, limit_right){  //某种插值算法,未使用
                let p = +percent;
                p = p<limit_left? limit_left: p>limit_right? limit_right: p;
                //log(p+' - '+bar_width+' - '+(limit_right-limit_left));
                let limits = limit_right - limit_left;
                let quo = Math.floor((p-limit_left)*bar_width/limits);
                let rem = (p-limit_left)*bar_width%limits;
                //log(quo+'****'+rem);
                return (bb_type === BILI_3_X)? Math.round((p-limit_left)/limits*bar_width): (rem>=(limits/2)? quo+1: quo);  //百分比对应进度条位置
            }

            function calc_bar_offset(percent, bar_width, limit_left, limit_right){
                let p = Math.max(Math.min(+percent, limit_right), limit_left);
                //log(p+' - '+bar_width+' - '+(limit_right-limit_left));
                let limits = limit_right - limit_left;
                let bar_offset = (p-limit_left) / limits * bar_width;
                return Math.round(bar_offset);  //百分比对应进度条位置
            }

            let selector = document.querySelector(selector_str);
            let e1 = new MouseEvent('mousedown'), e2 = new MouseEvent('mouseup');

            if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"flex"});
            $(bb['dmWrap']).css({"display":"block"});

            let selector_rect = selector.getClientRects();
            //log(selector.getBoundingClientRect()[0]+' - '+selector_rect[0]);
            let bar_offset = calc_bar_offset(percent, $(`${selector_str} ${bb['progressWrap']}`).innerWidth(), limit_left, limit_right);
            //log('wrapWIdth: '+ calc_bar_len(percent, $(`${selector_str} ${bb['progressWrap']}`).innerWidth(), limit_left, limit_right));
            for(let i=0;i<10;i++){
                let dest_per = Math.max(Math.min(+percent, limit_right), limit_left);
                let clientX = selector_rect[0].left + bar_offset;
                e1.initMouseEvent('mousedown',1,1,window,1,0,0,clientX,0,0,0,0,0,0,null);
                e2.initMouseEvent('mouseup'  ,1,1,window,1,0,0,clientX,0,0,0,0,0,0,null);
                selector.dispatchEvent(e1); selector.dispatchEvent(e2);
                let curr_per = +$(`${selector_str} ${bb['progressVal']}`).text().slice(0,-1);
                //log(curr_per+' - '+dest_per);
                if(curr_per !== dest_per){
                    curr_per < dest_per ? ++bar_offset : --bar_offset;
                    //log(bar_offset);
                }else{
                    break;
                }
            }

            $(bb['dmWrap']).css({"display":"none"});
            if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"none"});

            //激活设置,记忆进度条位置
            if(bb_type === BILI_3_X){
                $(bb['dm'])[0].dispatchEvent( new MouseEvent('mouseleave') );  //3.X
            }else{
                $(bb['dm'])[0].dispatchEvent( new MouseEvent('mouseout') );  //2.X
            }

            return $(`${selector_str} ${bb['progressVal']}`).text();
        }

        /*
         * 调节弹幕设置进度条
         * 利用系统mousedown事件
         * '正数': right,  '负数': left,  -100 ~ +100
         */
        function adjust_progress(selector_str, inc_percent, limit_left, limit_right){
            var curr_percent = Number($(`${selector_str} ${bb['progressVal']}`).text().slice(0,-1));
            return set_progress(selector_str, curr_percent + inc_percent, limit_left, limit_right);
        }

        //滚轮调节弹幕透明度(ctrl),参数表示滚动一下增加的透明度百分比
        function wheel_opacity(status, delta=5){
            $(bb['videoWrap']).off('mousewheel.hhh_opacity');
            if(status === OFF) return;
            $(bb['videoWrap']).on('mousewheel.hhh_opacity', function(e){
                if(e.ctrlKey === true) {
                    //阻止页面滚动 && 阻止冒泡
                    e.preventDefault();
                    e.stopPropagation();
                    //缺省透明度百分比,默认5
                    delta = (delta<1 || delta>100)? 5: delta;
                    var wheelDelta = e.originalEvent.wheelDelta;
                    var opacity;
                    if(wheelDelta >= 120) {  //向上滚动,增大透明度
                        opacity = adjust_progress(bb['settingOpacity'], delta, 10, 100);
                    } else if(wheelDelta <= -120) {  //向下滚动,减少透明度
                        opacity = adjust_progress(bb['settingOpacity'], -delta, 10, 100);
                    }
                    if(opacity !== undefined) showHint(document, '#hhh_opacityHint', '透 '+opacity);
                }
            });
        }

//        /  \
//        |  |
//        \  /
//clip-path: polygon(40% 0%, 25% 30%, 25% 70%, 40% 100%, 0% 100%, 0% 0%,60% 0%, 75% 30%, 75% 70%, 60% 100%, 100% 100%, 100% 0%);

//         <div style="width:200px;height:200px;background:red;clip-path: url(#myClip);">

// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	<div>11111111111111111111111</div>
// 	</div>

// <svg width="0" height="0">
//   <defs>
//     <clipPath id="myClip">
//       <circle cx="100" cy="100" r="40"/>
//       <circle cx="60" cy="60" r="40"/>
//     </clipPath>
//   </defs>
// </svg>

//         $('.bilibili-player-context-menu-container.active li:last').mouseenter(function(){
//     let hotkey_class = '.bilibili-player-hotkey-panel-container'.substr(1);
//     $('#hhh_hotkey_panel').clone(true,true).replaceAll($(`.${hotkey_class}:last`)).attr({'id': '', 'class': hotkey_class, 'style': ''});
//     let $hotkey = $('.bilibili-player-hotkey-panel-container').addClass('active').css('z-index', $('.bilibili-player-video-control-wrap').css('z-index'));
// }).mouseleave(function(){
//     $('.bilibili-player-hotkey-panel-container').removeClass('active').css('display', 'none');
// })

// BV to AV
//         // 作者:mcfx
//         // 链接:https://www.zhihu.com/question/381784377/answer/1099438784
//         // 来源:知乎
//         // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
//         function bv2av() {
//             const bv = document.getElementById('bv').value;
//             document.getElementById('av').value = dec(bv);
//         }

//         function av2bv() {
//             const av = +document.getElementById('av').value;
//             document.getElementById('bv').value = enc(av);
//         }

//         const table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
//         const tr = {}
//         for (let i = 0; i < 58; i++)
//             tr[table[i]] = i
//         const s = [11, 10, 3, 8, 4, 6]
//         const xor = 177451812
//         const add = 8728348608

//         function dec(x) {
//             let r = 0
//             for (let i = 0; i < 6; i++) {
//                 r += tr[x[s[i]]] * 58 ** i
//             }
//             return (r - add) ^ xor
//         }
//         function enc(x) {
//             x = (x ^ xor) + add
//             r = 'BV1  4 1 7  '.split('')
//             for (let i = 0; i < 6; i++) {
//                 r[s[i]] = table[parseInt(x / 58 ** i) % 58]
//             }
//             return r.join('')
//         }

//         // console.log(dec('BV17x411w7KC'))
//         // console.log(dec('BV1Q541167Qg'))
//         // console.log(dec('BV1mK4y1C7Bz'))
//         // console.log(enc(170001))
//         // console.log(enc(455017605))
//         // console.log(enc(882584971))
//         // console.log('----------------------------');
//         // console.log(1, enc(1))
//         // console.log(93761707, dec(enc(93761707)))
//         // console.log('BV1xE411x7Mn', enc(dec('BV1xE411x7Mn')))
//         // console.log(add === 100618342136696320, add);

        //自定义快捷键说明页面
        function set_custom_hotkey($hotkey, sub_class, hotkey, is_append) {
            var $hotkey_panel = bb_type.indexOf(BILI_2_X) !== -1 ? $hotkey.find(`.${sub_class}:first`) : $hotkey.find(`.${sub_class}:first`);
            var $hotkey_item  = $hotkey.find(`.${sub_class}-item:first`);
            var key_name = bb_type.indexOf(BILI_2_X) !== -1 ? 'key' : 'name';
            if(is_append === false) $hotkey_panel.empty();
            for (let [key, { value, text }] of Object.entries(hotkey)) {
                $hotkey_item.clone().appendTo($hotkey_panel);
                let $hotkey_key = $hotkey_panel.find(`.${sub_class}-${key_name}:last`);
                $hotkey_key.text(value);;
                $hotkey_key.next().text(text).width(180);  // 3.X 默认宽度窄了
            }
        }

        //自定义快捷键说明页面
        function add_custom_hotkey(hotkey_panel_class, hotkey, is_append) {
            var $hotkey_panel = $(`.${hotkey_panel_class}`);
            var $hotkey_item  = $hotkey_panel.find(`.${hotkey_panel_class}-item:first`);
            var key_name = bb_type.indexOf(BILI_2_X) !== -1 ? 'key' : 'name';
            if(is_append === false) $hotkey_panel.empty();
            for (let [key, { value, text }] of Object.entries(hotkey)) {
                $hotkey_item.clone().appendTo($hotkey_panel);
                let $hotkey_key = $hotkey_panel.find(`.${hotkey_panel_class}-${key_name}:last`);
                $hotkey_key.text(value);;
                $hotkey_key.next().text(text).width(180);  // 3.X 默认宽度窄了
            }
        }

        //添加右键菜单自定义快捷键说明2.X
        function add_custom_hotkey_menu_2_X(custom_hotkey) {
            //主class名,去掉"."
            let hotkey_panel_class = 'bilibili-player-hotkey-panel',
                is_init = false;

            //设置右键 & 快捷键菜单
            (function add_menu(){
                $('#bilibiliPlayer')[0].addEventListener('DOMSubtreeModified', function(e) {
                    let $target = $(e.target);
                    if($target.hasClass('context-line context-menu-function hover') && $('.bilibili-player-hotkey-panel').length === 1){
                        if(is_init === false){
                            //log('-------添加快捷键菜单--------');
                            is_init = true;
                            let $last_item = $('.bilibili-player-hotkey-panel').find('.bilibili-player-hotkey-panel-item:last');
                            $last_item.attr('id', 'hhh_last_system_hotkey_panel_item');
                            add_custom_hotkey(hotkey_panel_class, custom_hotkey, true);
                        }else if($target[0].id !== '__sizzle__'){  //过滤掉第一个懒加载
                            let $last_system_itme = $('#hhh_last_system_hotkey_panel_item');
                            if($target.find('a').text() === '快捷键说明'){
                                    //log('--------显示快捷键说明-------');
                                    $last_system_itme.prevAll().css('display','block');
                                    $last_system_itme.css('display','block');
                                    $last_system_itme.nextAll().css('display','none');
                            }else if($target.find('a').text() === '快捷键说明(bilibili关灯)'){
                                    //log('--------显示快捷键说明(bilibili关灯)-------');
                                    $last_system_itme.prevAll().css('display','none');
                                    $last_system_itme.css('display','none');
                                    $last_system_itme.nextAll().css('display','block');
                            }
                        }
                    } else if($target.hasClass('bilibili-player-context-menu-container black bilibili-player-context-menu-origin') &&  $target[0].id === '') {  //还有一个id = __sizzle__
                        this.removeEventListener('DOMSubtreeModified', arguments.callee);
                        //log('--------添加右键菜单-------');
                        let $li_sys_hotkey = $target.find('a:contains("快捷键说明"):first').parent();  //返回li,XXX: 此时contains("快捷键说明")多于一个
                        let $a_hhh_hotkey = $target.find('a:contains("快捷键说明(bilibili关灯)")');
                        var $li_hhh_hotkey = ($a_hhh_hotkey.length && $a_hhh_hotkey.parent()) || $li_sys_hotkey.clone(false, false).insertAfter($li_sys_hotkey).css('display', '').find('a').text('快捷键说明(bilibili关灯)');  //插入自定义快捷键

                        add_menu();
                    }
                });
            })();
        }

        //添加右键菜单自定义快捷键说明3.X
        function add_custom_hotkey_menu_3_X(custom_hotkey) {
            //主class名,去掉"."
            var player_hotkey_panel_class = 'bpx-player-hotkey-panel';

            //监听右键菜单,生成自定义快捷键说明页面,只执行一次
            (function add_custom_hotkey(){
                //$(bb['videoWrap'])[0].addEventListener('DOMNodeInserted', function(e) {
                $('.bpx-player-container')[0].addEventListener('DOMNodeInserted', function(e) {

                    let $target = $(e.target);
                    if($target.hasClass(player_hotkey_panel_class)) {
                        this.removeEventListener('DOMNodeInserted', arguments.callee);

                        //var $hotkey = $target.css('display', 'none');
                        var $hotkey = $target;
                        $hotkey.clone(true,true).insertBefore($hotkey).attr({'class': '','id': 'sys_hotkey_panel'}).css('display', 'none')
                                                                      .find(`.${player_hotkey_panel_class}-area`).css('max-height', '600px');  //bilibili自己的BUG,由于max-height限制,显示不全
                        $hotkey.clone(true,true).insertBefore($hotkey).attr({'class': '','id': 'hhh_hotkey_panel'}).css('display', 'none')
                                                                      .find(`.${player_hotkey_panel_class}-area`).css('max-height', '600px');

                        $('#sys_hotkey_panel .bpx-player-hotkey-panel-close').click(function(){ $(this).parent().parent().css('display', 'none') });  //jquery问题,clone失败,自定义关闭按钮事件
                        $('#hhh_hotkey_panel .bpx-player-hotkey-panel-close').click(function(){ $(this).parent().parent().css('display', 'none') });  //jquery问题,clone失败,自定义关闭按钮事件

                        //自定义快捷键说明页面
                        set_custom_hotkey($('#hhh_hotkey_panel'), `${player_hotkey_panel_class}-content`, custom_hotkey, false);
                    }
                });
            })();

            //右键菜单弹出时添加项
            (function add_menu(){
                $('#bilibili-player')[0].addEventListener('DOMSubtreeModified', function(e) {
                    let $target = $(e.target);
                    if($target.hasClass('bpx-player-contextmenu bpx-player-black') &&  $target[0].id === '') {  //还有一个id = __sizzle__
                        this.removeEventListener('DOMSubtreeModified', arguments.callee);

                        if($target.find('li:contains("快捷键说明"):first').length === 1) {
                            var $li_sys_hotkey = $target.find('li:contains("快捷键说明"):first');  //XXX: 此时contains("快捷键说明")多于一个
                            var $li_hhh_hotkey = $li_sys_hotkey.clone(false, false).insertAfter($li_sys_hotkey).css('display', '').text('快捷键说明(bilibili关灯)');

                            $li_sys_hotkey.mousedown(function(){
                                $('#sys_hotkey_panel').clone(true,true).replaceAll($(`.${player_hotkey_panel_class}:last`)).attr({'id': '', 'class': player_hotkey_panel_class, 'style': ''});
                            });
                            $li_hhh_hotkey.mousedown(function(){
                                $('#hhh_hotkey_panel').clone(true,true).replaceAll($(`.${player_hotkey_panel_class}:last`)).attr({'id': '', 'class': player_hotkey_panel_class, 'style': ''});
                            });
                        }

                        add_menu();
                    }
                });
            })();

            //模拟右键菜单消息,激活菜单
            let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 });
            $(bb['videoWrap'])[0].dispatchEvent(evt);

            //模拟点击菜单,激活热键菜单DOM
            evt = new MouseEvent('mousedown',{ bubbles:true });
            $(`.bpx-player-contextmenu.bpx-player-black li:contains("快捷键说明")`)[0].dispatchEvent(evt);

            //关闭热键菜单
            $('.bpx-player-hotkey-panel-close').click();
        }

        //添加右键菜单自定义快捷键说明
        function add_custom_hotkey_menu(hotKeyMenu) {
            if(bb_type.indexOf(BILI_2_X) !== -1) add_custom_hotkey_menu_2_X(hotKeyMenu);
            else add_custom_hotkey_menu_3_X(hotKeyMenu);
        }

        //取得版本号-未使用
        //function get_ver() {
        //    if(bb_type.indexOf(BILI_2_X) !== -1) ver = bili_player.getVersion().version;
        //    else ver = $('.bpx-common-opacity-60').text().split('-')[0];
        //}

        //取得视频FPS(Frames Per Second)和版本
        function get_video_fps_ver() {
            $(bb['videoWrap'])[0].addEventListener('DOMNodeInserted', function(e) {
                //插入info面板时截取fps值
                if($(e.target).hasClass(bb['DOMNodeInsertedVideoInfoShow'].substr(1))) {
                    this.removeEventListener('DOMNodeInserted', arguments.callee);

                    let $video_info_close = $(bb['videoInfoClose']);
                    $video_info_close.click();  //模拟关闭统计信息面板,2.X版本一次即可关掉
                    $video_info_close.click();  //3.X版本执行两次才能关掉面板,保险起见3次
                    $video_info_close.click();  //估计是点击事件开始太快,系统未能处理,也可能3.X测试版自己的问题

                    //text中取得fps值
                    var get_title_text = function(title) { return $(bb['videoInfoContainer']).find(`.info-title:contains("${title}")`).next().text(); }
                    fps = Number(get_title_text('Resolution').match(/\d+\.\d+/)) || Number(get_title_text('FPS')) || 30;
                }
            })

            //模拟右键菜单消息,激活菜单DOM
            let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 });
            $(bb['videoContextMenu'])[0].dispatchEvent(evt);

            //模拟点击菜单,激活热键菜单DOM,版本号
            if(bb_type.indexOf(BILI_2_X) !== -1){
                let evt = new MouseEvent('click',{ bubbles:true });
                $(`${bb['playerContextMenu']} a:contains("视频统计信息")`)[0].dispatchEvent(evt);
                ver = $(`${bb['playerContextMenu']} a:contains("更新历史")`).text().split(' ')[1].split('-')[0];
            }
            else if(bb_type === BILI_3_X) {
                let evt = new MouseEvent('mousedown',{ bubbles:true });
                $(`${bb['playerContextMenu']} li:contains("视频统计信息")`)[0].dispatchEvent(evt);
                ver = $(`${bb['playerContextMenu']} li:contains("更新历史")`).text().match(/\S+/g)[1].split('-')[0];
            }
        }

        //笨办法,激活系统音量设置,复制volumeHint DOM
        function pick_volume_hint(){
            var original_volume = h5Player.volume;
            //监视提取提示DOM
            $(bb['videoWrap'])[0].addEventListener('DOMNodeInserted', function(e) {
                if($(e.target).hasClass(bb['volumeHint'].substr(1))) {
                    this.removeEventListener('DOMNodeInserted', arguments.callee);

                    volume(original_volume);  //模拟鼠标拖动无法按1%精确控制音量,系统自身限制或者说bug

                    //添加 volumeHint wordsHint opacityHint DOM
                    $(bb['volumeHint']).clone().appendTo(bb['videoWrap']).attr('id','hhh_volumeHint');

                    $('#hhh_volumeHint').clone().appendTo(bb['videoWrap']).attr('id','hhh_wordsHint').css({'opacity': 0, 'display': 'none'}).find(bb['volumeHintIcon']).remove();
                    $('#hhh_wordsHint').clone().appendTo(bb['videoWrap']).attr('id','hhh_opacityHint');

                    if(bb_type.indexOf(BILI_2_X) !== -1){
                        $('#hhh_wordsHint').css({'width':'auto','margin-left':'0px','padding-left':'8px','padding-right':'15px','transform':'translate(-50%)'})
                                           .find(bb['volumeHintText']).css({'width': 'auto', 'padding-left': '10px'});
                        $('#hhh_opacityHint').find(bb['volumeHintText']).css({'padding-right': '6px'});
                    }
                    else{
                        $('#hhh_wordsHint, #hhh_opacityHint').find(bb['volumeHintText']).css({'padding': '0 10px'});
                    }

                    //隐藏提示
                    $(bb['volumeHint']).css({"visibility":"hidden"});
                }
            });
            //激活系统音量设置,复制volumeHint DOM
            let evt = new KeyboardEvent('keydown', { keyCode:keycode['up'] });
            window.dispatchEvent(evt);
        }

        //快进时显示醒目进度条
        function dynamicProgress(dynamicHeight, staticHeight){
            if(bb_type.indexOf(BILI_2_X) !== -1) {
                if (1||$('.bilibili-player-area').hasClass('progress-shadow-show') === true) {
                    $('.bilibili-player-video-progress-shadow .bui-track-video-progress').css('cssText', `height:${dynamicHeight}px !important`);
                    clearTimeout(document.showVideoProgress);
                    document.showVideoProgress = window.setTimeout((function() { $('.bilibili-player-video-progress-shadow .bui-track-video-progress').css('cssText', `height:${staticHeight}px !important`); }), 2000);
                }
            } else {
                if(1||$('.bpx-player-container').hasClass('bpx-state-no-cursor') === true) {
                    $('.squirtle-progress-buffer').css({'height': `${dynamicHeight/2}px`});
                    $('.squirtle-progress-timeline').css({'height': `${dynamicHeight/2}px`});
                    $('.squirtle-progress-totalline').css({'height': `${dynamicHeight/2}px`});
                    clearTimeout(document.showVideoProgress);
                    document.showVideoProgress = window.setTimeout((function() {
                        $('.squirtle-progress-buffer').css({'height': `${staticHeight}px`});
                        $('.squirtle-progress-timeline').css({'height': `${staticHeight}px`});
                        $('.squirtle-progress-totalline').css({'height': `${staticHeight}px`});
                    }), 2000);
                }
            }
        }

        //调节视频倍速
        function video_select_speed(level) {
            let data_x = ['0.5x', '0.75x', '1.0x', '1.25x', '1.5x', '2.0x'];
            let curr_x = $(bb['videoSpeedActive']).text();
            let x = data_x[data_x.indexOf(curr_x) + level];
            if(x !== undefined) $(`${bb["videoSpeed"]}:contains("${x}")`).click();
            showHint(parent, '#hhh_wordsHint', $(bb['videoSpeedName']).text());
        }

        //修复选择历史弹幕时弹幕填装信息丢失问题
        function fix_danmaku_info() {
            if(bb_type.indexOf(BILI_2_X) !== -1) {
                //log($('.danmaku-box').length);
                $('.danmaku-box')[0].addEventListener('DOMSubtreeModified', function(e) {
                    if($(e.target).hasClass('player-auxiliary-danmaku-list bpui-component bpui-undefined bpui-selectable') && $('.bilibili-player-video-info').hasClass('bilibili-player-hide-dm')) {
                        $('.bilibili-player-video-info').removeClass('bilibili-player-hide-dm');
                        //得到弹幕数
                        let danmaku_number = $('.player-auxiliary-danmaku-contaner .player-auxiliary-danmaku-list').height()/$('.danmaku-info-row:first').height();
                        $('.bilibili-player-video-info-danmaku-number').text(danmaku_number);
                    }
                });
            } else {
                $('.bpx-player-video-info')[0].addEventListener('DOMSubtreeModified', function(e) {
                    if($(e.target).hasClass('bpx-player-video-info-dm') && $('.bpx-player-video-info').hasClass('bpx-player-hide-dm')) {
                        $('.bpx-player-video-info').removeClass('bpx-player-hide-dm');
                    }
                });
            }
        }

        //初始化自定义设置 节点 事件 tips
        //setting - wrap - box | wrap - move - item
        function init_setting(run_default_setting_flag){
            var $DSet = $(bb['dm']);
            var $wrap = $DSet.find('.bui-panel-wrap');
            var $move = $DSet.find('.bui-panel-move');
            var $item_0 = $DSet.find('.bui-panel-item:eq(0)');
            var $item_1 = $DSet.find('.bui-panel-item:eq(1)');
            var $item_2;
            var old_width = $item_0.width() + $item_1.width();
            var item_0_height = $item_0.height() + 36;
            var item_2_width = $item_0.width() + 20;
            var item_2_height = 452+22*2;

            //
            if($DSet.length!=1 || $wrap.length!=1 || $move.length!=1) log('init_setting失败');
            if($item_0.length!=1 || $item_1.length!=1) log('init_setting失败2');

            /*-----------------------------------
             * 初始化
             *----------------------------------*/
            //初始化【$item_0】高度
            $item_0.css('height', item_0_height);
            $item_0[0].hhh_new_height = item_0_height;

            //初始化【$move】宽度
            $DSet.find('.bui-panel-move').css('width', old_width + item_2_width);

            /*-----------------------------------
             * 复制所需节点
             *----------------------------------*/
            //复制【item_0】【高级设置】To【自定义设置】
            $(bb['dmLeftMore']).clone().appendTo(bb['dmLeft']).attr('id', 'hhh_more')
                                                              .css('top', '20px')
                                                              .find(bb['dmLeftMoreText']).text('自定义设置');
            //复制【item_1】 To 【item_2】
            $item_2 = $item_1.clone().appendTo($move).attr('id', 'hhh_item')
                                                     .css({'width':item_2_width, 'height':item_2_height})
                                                     .removeClass('bui-panel-item-active')
                                                     .find('div *').remove().end();
            //复制【分割线】模板
            var $separator = $item_1.find(`${bb['dmRightSeparator']}:first`).clone();

            //复制【$title $hotkey父节点】模板
            var $title_div = $item_0.find(bb['dmLeftBlock']).clone().attr('id', 'hhh_title_div')
                                                                    //.css({'display': 'flex', 'flex-direction': 'column'})
                                                                    .empty().css({'margin-top': 6, 'margin-bottom': 2, 'height': 32+0});

            //复制【title】模板
            var $title = $item_0.find(bb['dmLeftBlockTitle']).clone().css({'color': '#12b3e8'})
                                                                     .css({'display': 'inline-flex', 'line-height': '32px'})
                                                                     .text('bilibili关灯自定义设置');
            //复制【快捷键说明】模板
            var $hotkey = $item_1.find(bb['dmRightMore']).clone().attr('id', 'hhh_item_2_hotkey')
                                                                 .css({'display': 'inline-flex', 'float': 'right'})
                                                                 .find('span:first').remove().end()
                                                                 .find(bb['dmRightMoreText']).text('快捷键说明(点击切换)').end();
            //
            var $div = $('<div></div>');
            var $middle_div = $div.clone().css({'display':'flex', 'justify-content':'space-between'});
            //复制【封面】模板
            var $cover = $item_1.find(bb['dmRightMore']).clone().attr('id', 'hhh_item_2_cover')
                                                                 //.css({'display': 'inline-flex', 'float': 'right', 'flex-direction': 'row-reverse'})
                                                                 //.css({'float': 'right'})
                                                                 .find('span:first').remove().end()
                                                                 .find(bb['dmRightMoreText']).text('显示封面(点击切换)').end();
            //复制【input-checkbox父节点】模板
            var $input_div = $item_0.find(bb['dmLeftBlock']).clone().attr('id', 'hhh_input_div')
                                                                    .empty().css({'margin-top': 4, 'margin-bottom': 2})
                                                                    //.css('background', 'blue')
                                                                    //.css('width', 200)
                                                                    ;
            //复制【更多其他】模板
            var $more_div = $item_0.find(bb['dmLeftBlock']).clone().attr('id', 'hhh_input_div2')
                                                                    .empty().css({'margin-top': 4, 'margin-bottom': 2})
                                                                    //.css('background', 'red')
                                                                    //.css('width', 100).css('height', 100)
                                                                    ;

            //复制【input-checkbox】模板
            var $input = $item_1.find(bb['dmRightDensity']).clone().css({'display': 'flex', 'margin-top': '6px'})  //inline-flex
                                                                   .find('input').removeAttr('aria-label').prop('checked', false).end()
                                                                   .find('.bui-checkbox-name').text('bilibili关灯').end();
            //复制【恢复默认设置】模板
            var $reset = $item_1.find(bb['dmRightReset']).clone().css({'margin-top': 2, 'margin-bottom': 6});

            //复制【返回】模板
            var $reback = $item_1.find(bb['dmRightMore']).clone().attr('id', 'hhh_item_2_more')
                                                                 .css({'margin-top': 2})
                                                                 .find(bb['dmRightMoreText'])
                                                                 .text('返回').end();
            /*-----------------------------------
             * 添加节点
             *----------------------------------*/
            let $item_2_div = $item_2.children(':first');

            /*-----------------------------------
             * 上部div
             *----------------------------------*/
            //添加title hotkey
            $title_div.appendTo($item_2_div);
            $title.clone().appendTo($title_div);
            $hotkey.clone().appendTo($($title_div));
            //添加分割线
            $separator.clone().appendTo($item_2_div);

            /*-----------------------------------
             * 中部div
             *----------------------------------*/
            $middle_div.appendTo($item_2_div);
            $input_div.appendTo($middle_div);
            $more_div.appendTo($middle_div);
            //添加 & 初始化【checkbox】
            for (let [key, { text, status, args, show }] of Object.entries(config.sets)) {
                if(show === OFF) continue;
                $input.clone().appendTo($input_div).attr('id', key)
                                                   .find('input').prop('checked', status).end()
                                                   .find('.bui-checkbox-name').text(text);

                if(key === 'volumeControlWhenNonFullScreen')
                    config.setCheckboxSettingTips('volumeControlWhenNonFullScreen', `在屏幕中间${Math.round((args.screenRight-args.screenLeft)*100)}%范围内调节,步幅${args.delta}%`);
            }
            //添加恢复默认设置
            $reset.clone().appendTo($input_div);
            //添加封面
            $cover.appendTo($more_div);

            /*-----------------------------------
             * 下部div
             *----------------------------------*/
            //添加分割线
            $separator.clone().appendTo($item_2_div);
            //添加返回
            $reback.clone().appendTo($item_2_div);

            /*-----------------------------------
             * 添加事件等
             *----------------------------------*/
            //重设置【设置按钮】
            // $DSet.mouseenter(function(){
            //     $wrap.css('height', $DSet.find('.bui-panel-item-active').css('height'));
            // })

            //重设置【item_0 - 自定义设置】
            $('#hhh_more').click(function(){
                $wrap.css({'height': $item_2.css('height'), 'width': $item_2.css('width')});
                $move.css('transform', `translateX(-${old_width}px)`);
                $DSet.find('.bui-panel-item-active').removeClass('bui-panel-item-active');
                $item_2.addClass('bui-panel-item-active');
            })

            //重设置【item_1 - 更多弹幕设置】
            $item_1.find(bb['dmRightMore']).click(function(){
                $wrap.css({'height': $item_0.css('height'), 'width': $item_0.css('width')});
            })

            //重设置【item_2 - 返回】
            $item_2.find('#hhh_item_2_more').click(function(){
                $wrap.css({'height': $item_0.css('height'), 'width': $item_0.css('width')});
                $move.css('transform', 'translateX(0px)');
                $DSet.find('.bui-panel-item-active').removeClass('bui-panel-item-active');
                $item_0.addClass('bui-panel-item-active');
            })

            //重设置【item_2 - 封面】
            $item_2.find('#hhh_item_2_cover').click(function(){
                if($('#hhh_img').length === 1){
                    let $hhh_img = $('#hhh_img');
                    //let width = $(bb['video']).width()*0.9;
                    //$('#hhh_img').css('width', width);
                    $hhh_img.css('display') === 'none'? $hhh_img.css('display', 'flex'): $hhh_img.css('display', 'none');
                } else {
                    let $img = $(`<img style="cursor:pointer" src="${$(bb['coverImg']).attr('content').replace('http:','https:')}" />`);
                    let $d = $div.clone().attr('id', 'hhh_img')
                                         .css({position: 'absolute', top:'50%', left:'50%', transform: 'translate(-50%,-50%)'})
                                         .css({'z-index':`${$(bb['playTipWrap']).css('z-index')}`})
                                         .css({'display':'flex'})
                                         //.css('width',width)
                                         .css({'align-items':'center','justify-content':'center'})
                                         .appendTo($(bb['videoWrap']));
                    $img.css({width:'100%', height:'auto'}).appendTo($d);
                    //重设置【item_2 - 封面 - IMG】
                    $('#hhh_img').click(function(){
                        $(this).css('display','none');
                        window.open($(bb['coverImg']).attr('content').replace('http:','https:'));
                    })
                    //let width = $(bb['video']).width()*0.9;
                    //log(width);
                    //if($img.width() > width) $('#hhh_img').css('width', 0);
                    //log($('#hhh_img').width());
                    //log($img.width());
                }
            })

            //重设置【item_2 - 快捷键说明】
            $item_2.find('#hhh_item_2_hotkey').click(function(){
                let is_active = bb_type.indexOf(BILI_2_X) !== -1 ? $(bb['hotkeyPanel']).hasClass('active') : $(bb['hotkeyPanel']).css('display') !== 'none';
                //2.X和3.X不一样?我来让你一样!
                if(is_active === false){
                    let hotkey_class = bb['hotkeyPanel'].substr(1);
                    $('#hhh_hotkey_panel').clone(true,true).replaceAll($(`.${hotkey_class}:last`)).attr({'id': '', 'class': hotkey_class, 'style': ''});
                    let $hotkey = $(bb['hotkeyPanel']).addClass('active').css('z-index', $(bb['playVideoControlWrap']).css('z-index')-1);

                    //同步显示
                    let wrap_left = $(bb['dmWrap']).position().left;
                    let box_left = $(bb['dmBox']).position().left;
                    $(bb['dmWrap']).css('left', wrap_left + $item_0.width());
                    $(bb['dmBox']).css('left', box_left - $item_0.width());
                    $(bb['dmWrap']).css('height', $hotkey.innerHeight());
                    $(bb['dmWrap']).css('width', $hotkey.innerWidth()-100);
                    $(bb['dmBox']).css('width', item_2_width);
                    //$(bb['dmWrap']).css('background', 'blue').css('opacity', 0.8);  //test


                    //同步隐藏
                    waitForTrue(()=> ($(bb['hotkeyPanel']).hasClass('active') === false && $(bb['hotkeyPanel']).css('display') === 'none') || $(bb['dmWrap']).css('display') === 'none', () => {
                        $(bb['hotkeyPanel']).removeClass('active').css('display', 'none');
                    });

                    let new_left = $item_2.offset().left + $item_2.width();
                    let new_top = $hotkey.offset().top + ($item_2.offset().top + $item_2.height()) - ($hotkey.offset().top + $hotkey.innerHeight());
                    $hotkey.offset({left:new_left, top:new_top}).find(bb['hotkeyPanelClose']).css('display', 'none');
                }else{
                    $(bb['hotkeyPanel']).removeClass('active').css('display', 'none');
                    $(bb['dmWrap'])[0].style.cssText = '';
                    $(bb['dmBox'])[0].style.cssText = '';
                    $(bb['dmWrap']).css('display', 'block');
                }
            })

            //set key
            function key_setting(key, status, fn, args){
                if(key === 'volumeControlWhenNonFullScreen'){
                    let pause_status = config.getCheckboxSettingStatus('volumeControlWhenPause');
                    eval(`${fn}(${status}, ${args.screenLeft}, ${args.screenRight}, ${args.delta}, ${pause_status})`);
                } else if(key === 'volumeControlWhenPause'){
                    let non_full_status = config.getCheckboxSettingStatus('volumeControlWhenNonFullScreen');
                    let fn = config.getCheckboxSettingFn('volumeControlWhenNonFullScreen');
                    let args = config.getCheckboxSettingArgs('volumeControlWhenNonFullScreen');
                    eval(`${fn}(${non_full_status}, ${args.screenLeft}, ${args.screenRight}, ${args.delta}, ${status})`);
                } else if(key === 'danmuOpacityControl'){
                    eval(`${fn}(${status}, ${args.delta})`);
                } else if(key === 'hotKeyHint'){
                    is_show_hint = config.getCheckboxSettingStatus(key);
                } else if(!!fn){ // openHotKey | removeVideoTopMask 等
                    eval(`${fn}(${status})`);
                    //Function(`${fn}(${status})`)();
                }
            }

            //重设置【item_2 - 恢复默认设置】
            $item_2.find(bb['dmRightReset']).click(function(){
                for (let [key, { text, status, tips, fn, args }] of Object.entries(config.b_playerCheckbox.options)) {
                    if(get_value(key) === status) continue;

                    $(`#${key}`).find('input').prop('checked', status);
                    set_value(key, status);
                    config.setCheckboxSettingStatus(key, status);

                    key_setting(key, status, fn, args);
                }
            })

            //设置【checkbox】选择
            $item_2.find('#hhh_input_div').click(function(e){
                if(e.target.type === 'checkbox'){
                    let key = bb_type.indexOf(BILI_2_X) !== -1 ? e.target.parentNode.id : e.target.parentNode.parentNode.parentNode.id;
                    let status = e.target.checked;
                    set_value(key, status);
                    config.setCheckboxSettingStatus(key, status);

                    let fn = config.getCheckboxSettingFn(key);
                    let args = config.getCheckboxSettingArgs(key);

                    key_setting(key, status, fn, args);
                }
            })

            //重设置【item_2 - 恢复默认设置】
            $DSet.on('mouseenter', function(){
                if ($(bb['dmWrap']).css('display') !== 'none') return;
                $item_0.css('height', $item_0[0].hhh_new_height);
                $wrap.css({'height': $item_0.css('height'), 'width': $item_0.css('width')});
                $move.css('transform', 'translateX(0px)');
                $DSet.find('.bui-panel-item-active').removeClass('bui-panel-item-active');
                $item_0.addClass('bui-panel-item-active');
                $(bb['dmWrap'])[0].style.cssText = '';
                $(bb['dmBox'])[0].style.cssText = '';
            })

            //set tips
            waitForTrue(()=> ($tip !== undefined && $(`#${Object.keys(config.sets)[0]}`).length === 1), () => {
                if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"flex"});
                $(bb['dmWrap']).css({"display":"block"});

                for (let [key, { text, status, tips }] of Object.entries(config.sets)) {
                    let $key = $(`#${key}`);
                    $key.width($key.find('label').width());  //调整宽度
                    !!tips && add_tip($tip, $key, {'text':tips, 'millisec':200, 'top':9, 'left':0});
                }

                $(bb['dmWrap']).css({"display":"none"});
                if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"none"});
            })

            //执行所有默认设置
            if(run_default_setting_flag === 'run_default_setting') $item_2.find(bb['dmRightReset']).click();

        }

        //自定义快捷键设置
        //ON - 启用热键,OFF - 关闭热键
        function set_hotkey(open){
            if (open !== ON){
                $(document).off('keyup.hhh_lightoff');
                $(document).off('keydown.hhh_lightoff');
            }else{
                var parent = document;
                var like_shake = false;
                var prev_time = 0;
                is_show_hint = config.getCheckboxSettingStatus('hotKeyHint');

                //up
                $(document).off('keyup.hhh_lightoff');
                $(document).on('keyup.hhh_lightoff',function(e){
                    if(!!e.target.type && e.target.type.toLowerCase().search(/text|textarea/) !== -1) return;
                    if(e.target.className === 'ql-editor') return;
                    if(e.keyCode === 'Y'.charCodeAt() || e.keyCode === 'O'.charCodeAt()) {  //点赞;长按一键三连
                        $(bb['like'])[0].dispatchEvent(new MouseEvent('mouseup'));
                        if(e.keyCode === 'Y'.charCodeAt() && like_shake === false) {
                            let like_text = $(bb['like']).text().match(/.+/)[0];
                            let like_num = like_text.match(/\d+$/)? (+like_text.match(/\d+$/)[0])+1: like_text;
                            if($(bb['likeon']).length === 1) showHint(parent, '#hhh_wordsHint', '取消点赞');
                            else showHint(parent, '#hhh_wordsHint', `点赞成功 ${like_num}`);
                            $(bb['like']).click();
                        }
                        like_shake = false;
                    }
                });

                //down
                $(document).off('keydown.hhh_lightoff');
                $(document).on('keydown.hhh_lightoff',function(e){
                    //log(!!e.target.type === true);
                    //log($(e.target.className));
                    //跳过输入框
                    if(!!e.target.type && e.target.type.toLowerCase().search(/text|textarea/) !== -1) return;
                    if(e.target.className === 'ql-editor') return;

                    //以下使用功能键
                    if(e.shiftKey && (e.keyCode === keycode['left'] || e.keyCode === keycode['right'])) {  //逐帧 shift+ left/right
                        h5Player.pause();
                        for(let move_frames = 1.01; move_frames>0.2;){
                            let move_frames_time = move_frames/fps;
                            h5Player.currentTime = e.keyCode === keycode['left']? +(h5Player.currentTime - move_frames_time).toFixed(3): +(h5Player.currentTime + move_frames_time).toFixed(3);
                            if(prev_time === h5Player.currentTime){  //如果未走帧
                                move_frames /= 2;
                                //log('2.1: '+h5Player.currentTime+' - '+prev_time+' - '+move_frames_time+' - '+move_frames);
                                continue;
                            }
                            else{
                                //log('2.2: '+h5Player.currentTime+' - '+prev_time+' - '+move_frames_time+' - '+move_frames);
                                let total_frame = +(h5Player.duration*fps).toFixed();
                                let current_frame = +(h5Player.currentTime*fps).toFixed();
                                showHint(parent, '#hhh_wordsHint', `${current_frame}/${total_frame}`);
                                prev_time = h5Player.currentTime;
                                break;
                            }
                        }
                        e.stopPropagation();
                    } else if(e.ctrlKey && (e.keyCode === keycode['left'] || e.keyCode === keycode['right'])) {  //+ -30s ctrl+ left/right
                        $(bb['danmakuSwitch']).last().find('input').click().click();
                        h5Player.currentTime = e.keyCode === keycode['left']? h5Player.currentTime - 30: h5Player.currentTime + 30;
                        h5Player.play();
                        dynamicProgress(16, 2);
                    } else if(e.ctrlKey && (e.keyCode === keycode['up'] || e.keyCode === keycode['down'])) {  //ctrl + -播放速度
                        if(config.getCheckboxSettingStatus('keyVideoSpeed') === OFF) return;
                        window.setTimeout((function() {  //长按时保持DOM更新
                            e.keyCode === keycode['up']? video_select_speed(1): video_select_speed(-1);
                        }),10);
                    } else if(e.ctrlKey && e.keyCode === keycode['Enter']) {  //全屏
                        fullscreen();
                    }

                    //以下不使用功能键
                    if(e.ctrlKey || e.altKey || e.shiftKey) return;

                    if(e.keyCode === 'A'.charCodeAt()){  //开关灯
                        is_show_hint && (is_lightoff() ? showHint(parent, '#hhh_wordsHint', '开灯') : showHint(parent, '#hhh_wordsHint', '关灯'));
                        lightoff_btn();
                    } else if(e.keyCode === 'W'.charCodeAt()) {  //网页全屏 Bb站改成点赞了
                        web_fullscreen();
                        e.stopPropagation();
                    } else if(e.keyCode === 'Q'.charCodeAt()) {  //宽屏模式 B站改成投币了
                        is_fullscreen() ? web_fullscreen() : wide_screen();
                        e.stopPropagation();
                    } else if(e.keyCode === 'D'.charCodeAt()) {  //开关弹幕 bilibili增加了关弹幕的快捷键,也是D
                        $(bb['danmakuSwitch']).last().find('input').click();
                        is_show_hint && (is_danmaku_show() === true ? showHint(parent, '#hhh_wordsHint', '开弹幕') : showHint(parent, '#hhh_wordsHint', '关弹幕'));
                        e.stopPropagation();
                    } else if(e.keyCode === 'T'.charCodeAt()) {  //开关顶部弹幕
                        $(bb['danmukuTopClose']).length === 0 ? showHint(parent, '#hhh_wordsHint', '关闭顶部弹幕') : showHint(parent, '#hhh_wordsHint', '打开顶部弹幕');
                        $(bb['danmukuTop']).click();
                        log('1111');
                    } else if(e.keyCode === 'B'.charCodeAt()) {  //开关底部弹幕
                        $(bb['danmukuBottomClose']).length === 0 ? showHint(parent, '#hhh_wordsHint', '关闭底部弹幕') : showHint(parent, '#hhh_wordsHint', '打开底部弹幕');
                        $(bb['danmukuBottom']).click();
                    } else if(e.keyCode === 'S'.charCodeAt()) {  //弹幕随屏幕缩放
                        $(bb['settingFs'])[0].checked === false ? showHint(parent, '#hhh_wordsHint', '弹幕随屏幕缩放') : showHint(parent, '#hhh_wordsHint', '弹幕不随屏幕缩放');
                        $(bb['settingFs']).click();
                    } else if(e.keyCode === 'R'.charCodeAt()) {  //开关洗脑循环  B站改成一键三连了
                        $(bb['playSettingRepeatInput'])[0].checked ? showHint(parent, '#hhh_wordsHint', '关洗脑循环') : showHint(parent, '#hhh_wordsHint', '开洗脑循环');
                        $(bb['playSettingRepeatInput']).click();
                        e.stopPropagation();
                    } else if(e.keyCode === 'Z'.charCodeAt() || e.keyCode === 'C'.charCodeAt()) {  //+ -弹幕透明度
                        let inc_percent = e.keyCode === 'Z'.charCodeAt()? -10: 10;
                        window.setTimeout((function() {  //长按时保持DOM更新
                            let opacity = adjust_progress(bb['settingOpacity'], inc_percent, 10, 100);
                            showHint(parent, '#hhh_opacityHint', '透 ' + opacity);
                        }),10);
                    } else if(e.keyCode === 'V'.charCodeAt() || e.keyCode === 'N'.charCodeAt()) {  //+ -弹幕字号
                        let inc_percent = e.keyCode === 'V'.charCodeAt()? -5: 5;
                        window.setTimeout((function() {  //长按时保持DOM更新
                            let opacity = adjust_progress(bb['settingFontsize'], inc_percent, 50, 170);
                            showHint(parent, '#hhh_opacityHint', '字 ' + opacity);
                        }),10);
                    } else if(e.keyCode >= '1'.charCodeAt() && e.keyCode <= '5'.charCodeAt()) {  //弹幕显示区域
                        var area_text = {0:'1/4屏',25:'半屏',50:'3/4屏',75:'不重叠',100:'不限'};
                        var percent = (e.keyCode - '1'.charCodeAt()) * 25;  //((0~4)*25)%
                        set_progress(bb['settingArea'], percent, 0, 100);
                        showHint(parent, '#hhh_wordsHint', area_text[percent]);
                    } else if(e.keyCode === keycode['left'] || e.keyCode === keycode['right']){  //快进时显示醒目进度条 && 段落循环
                        //log( $('#hhh_loop_wrap')[0].hhh_loop_playback_click );
                        if(0&&$('#hhh_loop_wrap')[0].hhh_loop_playback_click === true){
                            //log('快进时显示醒目进度条 && 段落循环');
                            return false;
                        }else{
                            if(config.getCheckboxSettingStatus('reloadDanmuku') === ON) {
                                //恢复重载弹幕效果
                                e.stopPropagation();
                                h5Player.currentTime = e.keyCode === keycode['left']? h5Player.currentTime - 5: h5Player.currentTime + 5;
                                h5Player.play();
                                setTimeout(function(){
                                    $(bb['danmakuSwitch']).last().find('input').click();
                                    $(bb['danmakuSwitch']).last().find('input').click();
                                },0);
                            }
                            dynamicProgress(16, 2);
                        }
                    } else if(e.keyCode === keycode['up'] || e.keyCode === keycode['down']) {  //音量控制,替换系统默认
                        //$(bb['volumeHint']).css({"visibility":"visible"}) //隐藏所有提示,避免提示重叠
                        //$(bb['volumeHint']).css('display', 'none');
                        let diff = e.keyCode === keycode['up']? 0.05: -0.05;
                        window.setTimeout((function() {  //长按时保持DOM更新
                            volume(volume()+diff);
                        }),10);
                        return false;
                    } else if(e.keyCode === keycode['space']) {  //空格键2.X版本不合理,改成和3.X版本一样,3.X版也O了
                        if(!is_fullscreen()){
                            if(is_in_biliplayer === false) e.stopPropagation()
                        }
                    } else if(e.keyCode === keycode['Esc']){  //优先取消右键菜单等
                        if($(bb['hotkeyPanel']).hasClass('active') === true || $(bb['hotkeyPanel']).css('display') !== 'none'){
                            $(bb['hotkeyPanel']).removeClass('active').css('display', 'none');
                            //$(bb['hotkeyPanel']).find(bb['hotkeyPanelClose']).click();  //慢
                            return false;
                        }
                        if($(bb['playerContextMenu']).hasClass('active') === true || $(bb['playerContextMenu']).hasClass('bpx-player-active') === true ){
                            let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 });
                            $(bb['videoWrap'])[0].dispatchEvent(evt);
                            return false;
                        }
                        if($('#hhh_img').length >= 1 && $('#hhh_img').css('display') !== 'none'){
                            $('#hhh_img').css('display', 'none');
                            return false;
                        }

                        //对应 系统快捷键 Q、R、W、E
                    } else if(e.keyCode === 'Y'.charCodeAt() || e.keyCode === 'O'.charCodeAt()) {  //长按一键三连
                        $(bb['like'])[0].dispatchEvent( new MouseEvent('mousedown') );
                        if(like_shake === false) like_shake = !!$('.van-icon-videodetails_like.shake').length;
                    } else if(e.keyCode === 'U'.charCodeAt()) {  //投币
                        $(bb['coin']).click();
                    } else if(e.keyCode === 'I'.charCodeAt()) {  //收藏
                        $(bb['collect']).click();

                        //TEST
                    } else if(e.keyCode === 'X'.charCodeAt() || e.keyCode === keycode['/']) {  //TEST 显示、隐藏video-control
                        if($(bb['playArea']).hasClass('video-control-show') === true) $(bb['playVideoControlWrap']).mouseout();
                        else $(bb['playVideoControlWrap']).mousemove();
                    } else if(e.keyCode === 'V'.charCodeAt()) {  //TEST
                        //if(bb_type===BILI_3_X) $('.bpx-player-dm-setting-wrap').css('display','block');
                        $('.bilibili-player-video-danmaku-setting-wrap').mouseover();
                        //$('.bilibili-player-area.video-state-blackside').attr('class', 'bilibili-player-area video-state-blackside video-state-pause video-control-show');
                    }else{
                        //console.dir(e.keyCode);
                    }
                });
            }
        }

        //因为遮挡弹幕,去掉全屏时鼠标悬停时产生的顶端mask
        function removeVideoTopMask(is_remove){
            let top_mask_class = bb['videoTopMask'].substr(1);
            if(is_remove === ON) $(bb['videoTopMask']).attr('id', top_mask_class).removeClass();
            else $(`#${top_mask_class}`).addClass(top_mask_class);
        }

        //播放关灯,暂停开灯,跳过充电
        function lightOffWhenPlaying(status){
            $(h5Player).off('play.hhh'); if(status === OFF) return;
            $(h5Player).on('play.hhh', ()=> !is_lightoff() && lightoff_btn());
        }
        function lightOnWhenPause(status){
            $(h5Player).off('pause.hhh'); if(status === OFF) return;
            $(h5Player).on('pause.hhh', ()=> is_lightoff() && lightoff_btn());
        }
        function jumpElectric(status){
            $(h5Player).off('ended.hhh'); if(status === OFF) return;
            $(h5Player).on('ended.hhh', ()=> $(bb['playJumpElectric']).click());
        }

        //双击或中键全屏
        function dblclickFullScreen(status){
            $(bb['videoWrap']).off('mousedown.hhh'); if(status === OFF) return;
            $(bb['videoWrap']).on('mousedown.hhh', function(e){
                if(e.button === 1 || e.button === 4 || e.button === 3) {  // 1中键
                    if(e.button === 1) web_fullscreen();
                    else fullscreen();
                    e.preventDefault(); e.stopPropagation();
                }
            });
            //$(bb['playTipWrap']).dblclick(function(){ fullscreen() });  //2.66自带双击全屏
        }

        //扩展播放倍速范围
        function extend_video_speed(e){
            let $speedul = $(bb['videoSpeedActive']).parent();
            let $li_0_1x = $speedul.find('li:first').clone(true, true).attr('data-value', '0.1').text('0.1x');
            $speedul.append($li_0_1x);
            let $li_3x   = $speedul.find('li:first').clone(true, true).attr('data-value', '3').text('3.0x');
            let $li_3_5x = $speedul.find('li:first').clone(true, true).attr('data-value', '3.5').text('3.5x');
            let $li_4x   = $speedul.find('li:first').clone(true, true).attr('data-value', '4').text('4.0x');
            let $li_4_5x = $speedul.find('li:first').clone(true, true).attr('data-value', '4.5').text('4.5x');
            let $li_5x   = $speedul.find('li:first').clone(true, true).attr('data-value', '5').text('5.0x');
            $speedul.prepend($li_3x); $speedul.prepend($li_3_5x); $speedul.prepend($li_4x); $speedul.prepend($li_4_5x); $speedul.prepend($li_5x);
            if(bb_type === BILI_3_X){
                $speedul.on('click', function(e){
                    let $li = $(e.target);
                    let speed = $li.attr('data-value');
                    if(speed !== undefined){
                        $li.addClass('active');
                        h5Player.playbackRate = speed;
                        $(bb['videoSpeedName']).text($li.text());
                    }
                })
            }
        }

        //主程序
        function run(){

            //防止重复加载
            if ($('#hhh_lightoff').length === 1) { log('重复加载'); return }

            //bpx test
            function bpx_test(){
                log('-------------------');
                log('ver: '+ver);
                log('fps: '+fps);
                log('------h5Player-----');
                dir(h5Player);
                log('currentTime  : '+h5Player.currentTime);
                log('duration     : '+h5Player.duration);
                log('playbackRate : '+h5Player.playbackRate);
                log('volume       : '+h5Player.volume);
                log('paused       : '+h5Player.paused);
                log('pause()      : '+'h5Player.pause()');
                log('videoHeight  : '+h5Player.videoHeight);
                log('videoWidth   : '+h5Player.videoWidth);
                log('-------------------');
            }

            /*-----------------------------------
             *初始化等
             *----------------------------------*/
            //保存设置信息 && 快捷键信息
            config.saveCheckboxSetting();

            for (let [key, { text, status }] of Object.entries(config.sets)) {
                if(get_value(key) === undefined) set_value(key, status);
                else config.sets[key]['status'] = JSON.parse(get_value(key));
            }

            //取得h5 video & window.player
            h5Player = ($(`${bb['video']} video`)[0] || $(`${bb['video']} bwp-video`)[0]);
            //bili_player = window.player;

            //初始化关灯按钮
            lightoff_init();

            //激活系统弹幕设置,以此调用系统网页全屏等
            $(bb['dm']).mouseenter().mouseleave();

            //保存tip
            $('.bilibili-player-video-danmaku-setting-left-ps').mouseover();
            waitForTrue(()=> $('.player-tooltips.tip.top-center.animation').length === 1, () => {
                $tip = $('.player-tooltips.tip.top-center.animation').clone().removeClass('active');
                $tip.find('.tooltip').css('background-color', 'rgba(0,0,0,0.9)');
                $('.bilibili-player-video-danmaku-setting-left-ps').mouseout();
            });

            //激活系统播放设置,以此调用系统关灯等
            //去掉mouseleave(),否则如果太快执行mouseleave()无法激活关灯class,应该是mouseenter()未执行完就被mouseleave打断了
            $(`${bb['playVideo']}${bb['playSetting']}`).mouseenter();

            //避免显示设置页面
            waitForNode(() => document.querySelector(bb['playSettingWrap']), (node) => {;
                $(node).css({"visibility":"hidden"});  //visible
            })

            //解决因为激活关灯class,导致全屏时滚轮操作(系统自带)无法调节音量的问题
            waitForTrue(()=> $(bb['playSettingWrap']).css('display') === 'block', () => {
                $(bb['playSettingWrap']).css('display', 'none').css('visibility', 'visible');
            });

            //取得视频fps
            get_video_fps_ver();

            //取得版本号
            //get_ver();

            //激活系统提示添加音量等自定义提示DOM
            pick_volume_hint();

            //添加自定义快捷键说明到右键菜单
            add_custom_hotkey_menu(config.hotKeyMenu);

            //初始化自定义设置
            init_setting();

            /*-----------------------------------
             *事件等
             *----------------------------------*/
            //点击关灯
            $(`#hhh_lightoff ${bb['switchInput']}:first`).click(function(){ lightoff_btn() });

            //判断当前鼠标点击焦点
            $(document).mouseup(function(e){
                if(e.originalEvent === undefined) return;
                let path = e.originalEvent.path;
                curr_focus = path[0];
                is_in_biliplayer = false;
                $(path).each(function(){
                    if(this.id === 'bilibili-player') { is_in_biliplayer = true; return; }
                })
                //隐藏封面 2.x && 3.x
                if(is_in_biliplayer == false || e.target.className === 'bilibili-player-dm-tip-wrap' || e.target.tagName.toLowerCase() === 'video'){
                    $('#hhh_img').css('display', 'none');
                }
            })

            //扩展播放倍速范围
            extend_video_speed();

            //修复选择历史弹幕时弹幕填装信息丢失问题
            fix_danmaku_info();

            //自动运行
            if(config.getCheckboxSettingStatus('autoPlay') === ON && $(bb['playSettingAutoplay'])[0].checked === false) $(bb['playSettingAutoplay']).click();//开启自动播放
            if(config.getCheckboxSettingStatus('lightOff') === ON) lightoff_btn();  //自动关灯
            if(config.getCheckboxSettingStatus('autoFullScreen') === ON) fullscreen();  //自动全屏
            if(config.getCheckboxSettingStatus('autoWebFullScreen') === ON) web_fullscreen();  //自动网页全屏
            if(config.getCheckboxSettingStatus('videoRepeat') === ON) $(bb['playSettingRepeatInput']).click();  //开启洗脑循环

            //双击或中键全屏
            dblclickFullScreen(config.getCheckboxSettingStatus('dblclickFullScreen'));

            //非全屏滚轮音量调节
            //两个参数指定屏幕范围(按百分比),第三个参数表示滚动一下增加的音量百分比,参数四表示暂停时是否调节
            let args = config.getCheckboxSettingArgs('volumeControlWhenNonFullScreen');
            wheel_volumeHint(config.getCheckboxSettingStatus('volumeControlWhenNonFullScreen'), args.screenLeft,args.screenRight,args.delta, config.getCheckboxSettingStatus('volumeControlWhenPause'));

            //滚轮调节弹幕透明度(ctrl),参数表示滚动一下增加的透明度百分比,默认5
            wheel_opacity(config.getCheckboxSettingStatus('danmuOpacityControl'), 5);

            //因为遮挡弹幕,去掉全屏时鼠标悬停时产生的顶端mask
            removeVideoTopMask(config.getCheckboxSettingStatus('removeVideoTopMask'));

            //播放关灯,暂停开灯,跳过充电鸣谢
            lightOffWhenPlaying(config.getCheckboxSettingStatus('lightOffWhenPlaying'));
            lightOnWhenPause(config.getCheckboxSettingStatus('lightOnWhenPause'));
            jumpElectric(config.getCheckboxSettingStatus('jumpElectric'));

            //记忆洗脑循环
            if(config.getCheckboxSettingStatus('rememberVideoRepeat') === ON && config.getCheckboxSettingStatus('videoRepeat') !== ON) {
                if(JSON.parse(get_value('hhh-rememberVideoRepeat', $(bb['playSettingRepeatInput'])[0].checked)) === true) $(bb['playSettingRepeatInput']).click();  //localStorage只能保存字符串
                $(bb['playSettingRepeatInput']).click(function() {
                    set_value('hhh-rememberVideoRepeat', $(bb['playSettingRepeatInput'])[0].checked);
                });
            };

            /*-----------------------------------
             *键盘控制
             *----------------------------------*/
            set_hotkey(config.getCheckboxSettingStatus('openHotKey'));

            /*设置界面
            //viewBox="10 8.5 10 12"
            $('.bilibili-player-video-danmaku-setting').clone(false,false).insertBefore($('#hhh_lightoff')).attr('id', 'hhh_setting')
            $('#hhh_setting>span>svg')[0].attributes[1].value = '10 8.5 10 12'
            $('#hhh_setting>span>svg>path:first').remove()
            */

            //段落循环
            loop_playback();

            //TEST
            bpx_test();
        }

        //段落循环
        function loop_playback(){
            var is_begin = true,
                first = true;

            function show_loop_time(sign_show){
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-cut-img').hide();
                if(sign_show !== 'sign_show') $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign').hide();
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').show();
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css('opacity',1);
            }
            function hide_loop_time(){
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css({display:''});
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-cut-img').show();
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign').show();
            }
            //loop显示状态切换
            function loop_state_switch(state){
                $('#hhh_loop_wrap')[0].hhh_loop_state_switch = state;
                let $p1 = $('#hhh_loop_1'), $p2 = $('#hhh_loop_2'), $bar = $('#hhh_loop_bar');
                if(state === 0){  //no loop
                    $p1.hide(), $p2.hide(), $bar.hide();
                }else if(state === 1){  //loop 1
                    if($p1[0].hhh_seconds) $p1.show();
                    if($p2[0].hhh_seconds) $p2.show();
                    if($p1[0].hhh_seconds && $p2[0].hhh_seconds) $bar.show();
                }else{  //loop 2
                    $p1.hide(), $p2.hide();
                    if($p1[0].hhh_seconds && $p2[0].hhh_seconds) $bar.show();
                }
            }
            //更新
            function loop_update($hhh_loop, o){
                //function PrefixZero(num, n) { return (Array(n).join(0) + num).slice(-n) }
                //time = PrefixZero(Math.floor(time/60),2) + ':' + PrefixZero(time%60,2);
                var left = 0,
                    seconds = 0,
                    rect = $('.bilibili-player-video-progress')[0].getBoundingClientRect();

                if(o.left !== undefined){
                    left = o.left - rect.x;
                    if(left < 0 || left > rect.width) return;
                    //Position To Time
                    seconds = Math.round(left/$('.bilibili-player-video-progress').width()*h5Player.duration);
                }else if(o.seconds !== undefined){
                    //Time To Position
                    left = o.seconds/h5Player.duration*$('.bilibili-player-video-progress').width();
                    if(left < 0 || left > rect.width) return;
                    seconds = o.seconds;
                }else{ log('参数错误',o); return;}

                //updata x
                $hhh_loop.css({left:left});
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css({left:left});

                //updata time
                $hhh_loop[0].hhh_seconds = seconds;
                function sec2str(t){
                    var d = Math.floor(t/86400),
                        h = (''+Math.floor(t/3600) % 24).slice(-2),
                        m = ('0'+Math.floor(t/60)%60).slice(-2),
                        s = ('0' + t % 60).slice(-2);
                    return (d>0?d+'d ':'')+(h5Player.duration>=3600?h+':':'')+m+':'+s;
                }
                let time = sec2str(seconds);
                $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text(time);

                //updata bar
                let t1 = $('#hhh_loop_1')[0].hhh_seconds;
                let t2 = $('#hhh_loop_2')[0].hhh_seconds;
                if(t1 && t2){
                    t1 = $('#hhh_loop_1').css('left').slice(0,-2);
                    t2 = $('#hhh_loop_2').css('left').slice(0,-2);
                    let begin = Math.min(t1,t2);
                    let end = Math.max(t1,t2);
                    $('#hhh_loop_bar').css({display:'block',width:`${end-begin}px`,left:`${begin}px`});
                }
            }
            //更新位置
            function resize_updata(){
                let $p1 = $('#hhh_loop_1');
                let $p2 = $('#hhh_loop_2');
                let $bar = $('#hhh_loop_bar');
                if($p1.length !== 1 || $p2.length !== 1 && $bar.length !== 1) return;

                let t1 = $p1[0].hhh_seconds;
                let t2 = $p2[0].hhh_seconds;
                let rect = $('.bilibili-player-video-progress')[0].getBoundingClientRect();
                let newleft = t1/h5Player.duration*rect.width;
                $p1.css('left', newleft);
                newleft = t2/h5Player.duration*rect.width;
                $p2.css('left', newleft);

                //log($p1.css('left'),$p2.css('left'));
                //log('------'+newleft);

                t1 = $p1.css('left').slice(0,-2);
                t2 = $p2.css('left').slice(0,-2);
                let begin = Math.min(t1,t2);
                let end = Math.max(t1,t2);
                $bar.css({left:begin, width:end-begin});
            }

            //css
            $('#hhh_head_style').remove();  //test
            if($('#hhh_head_style').length<1){
                $('head:first').append(`<style id="hhh_head_style" type="text/css">
                .hhh-bilibili-player-video-progress-detail {
                    position: absolute;
                    bottom: 7px;
                    left: 100px;
                    overflow: visible;
                    width: 20px;
                    height: 36px;
                    margin-left: -10px;
                    text-align: center;
                    z-index: 1;
                    pointer-events: none;
                    display: none;
                }
                .hhh-bilibili-player-video-progress-detail-sign {
                    cursor: pointer;
                    width: 8px;
                    height: 16px;
                    margin: 0 auto;
                    position: absolute;
                    overflow: hidden;
                    top: 27px;
                    left: 6px;
                }
                .hhh-bilibili-player-video-progress-detail-sign-down {
                    width: 0;
                    height: 0;
                    border-color: #FFA500 transparent transparent;
                    border-style: solid;
                    border-width: 4px;
                    position: relative;
                }
                .hhh-bilibili-player-video-progress-detail-sign-up {
                    margin-top: 8px;
                    width: 0;
                    height: 0;
                    border-color: transparent transparent #FFA500;
                    border-style: solid;
                    border-width: 4px;
                    position: relative;
                }
                </style>`);
            }

            //loop wrap
            let progheight = $('.bilibili-player-video-progress .bui-track').parent().css('height');
            //let progalignitem = $('.bilibili-player-video-progress .bui-track').parent().css('align-items');
            let progclass = $('.bilibili-player-video-progress .bui-track').parent().attr('class');
            $('.bilibili-player-video-progress .bui-track').wrap(`<div id="hhh_loop_wrap" class="${progclass}" style="width:100%; padding:0px"></div>`);
            $('#hhh_loop_wrap')[0].hhh_loop_state_switch = 1;
            //$('.bilibili-player-video-progress .bui-track').wrap(`<div id="hhh_loop_wrap" style="width:100%; height:${progheight}; display:flex; align-items:${progalignitem}"></div>`);

            let $bar = $('#hhh_loop_wrap').find('.bui-bar-wrap');
            let $schedule = $('#hhh_loop_wrap').find('.bui-schedule-wrap');
            $bar = $bar.length === 1? $bar: $schedule.length === 1? $schedule: log('not bui-bar-wrap  bui-schedule-wrap');
            $bar.children('div:first').clone(true,true).appendTo($bar)
                                      .css({transform:'scaleX(0.999999)'})  //配合其他transform,否则height不同,scaleX会改变height,bug?
                                      .css({background:'rgba(255,165,0,0.5)',display:'none'})
                                      .attr('id','hhh_loop_bar');

            //前后箭头node
            let detail = `<div id="hhh_id" class="hhh-bilibili-player-video-progress-detail" style="left:78.0475px;pointer-events:auto;z-index:-1">
                            <div class="bilibili-player-video-progress-detail-container" style="margin-left: -22px; width: 60px;">
                                <div class="bilibili-player-video-progress-detail-img" style="width: 60px; height: 18px;">
                                   <div class="bilibili-player-video-progress-detail-time" style="left:0px">00:01</div>
                                </div>
                            </div>
                            <div class="hhh-bilibili-player-video-progress-detail-sign">
                                <div class="hhh-bilibili-player-video-progress-detail-sign-down"></div>
                            </div>
                        </div>`;
            $('.bilibili-player-video-control-top').append(detail.replace(/hhh_id/, 'hhh_loop_1'));
            $('.bilibili-player-video-control-top').append(detail.replace(/hhh_id/, 'hhh_loop_2'));

            //设置起点和终点
            $('#hhh_loop_wrap')[0].hhh_loop_playback_click = false;
            $('#hhh_loop_wrap').mousedown(function(e){
                if(e.ctrlKey === true){
                    return false
                }
            }).mouseup(function(e){
                if(e.ctrlKey === true){
                    $('.bilibili-player-video-toast-wrp').css('z-index', 0);
                    loop_state_switch(1);
                    var begin_left = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css('left');
                    let $hhh_loop = is_begin? $('#hhh_loop_1'): $('#hhh_loop_2');
                    is_begin = !is_begin;
                    loop_update($hhh_loop, {left:e.pageX});
                    $hhh_loop.css({left:`${begin_left}`}).css('display', 'block');
                    let time = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text();
                    $hhh_loop.find('.bilibili-player-video-progress-detail-time').text(time);

                    this.hhh_loop_playback_click = $hhh_loop[0].id;

                    if(first === true){
                        first = false;

                        //判断当前鼠标点击焦点
                        $(document).mouseup(function(e){
                            if(!e.ctrlKey && $('#hhh_loop_wrap')[0].hhh_loop_playback_click) $('#hhh_loop_wrap')[0].hhh_loop_playback_click = false;
                        });

                        //time now
                        $('.bilibili-player-video-time-now')[0].addEventListener('DOMNodeInserted', function(e) {
                            if($('#hhh_loop_wrap')[0].hhh_loop_state_switch && $('#hhh_loop_wrap')[0].hhh_loop_state_switch !== 0){
                                let t1 = $('#hhh_loop_1')[0].hhh_seconds;
                                let t2 = $('#hhh_loop_2')[0].hhh_seconds;
                                let begin = Math.min(t1,t2);
                                let end = Math.max(t1,t2);
                                    //log(t1+' - '+t2);
                                if(h5Player.currentTime > end){
                                    //log(t1+' - '+t2);
                                    h5Player.currentTime = begin;
                                }
                            }
                        });

                        //拖动确定范围
                        $('#hhh_loop_1, #hhh_loop_2').mouseenter(function(e){
                            $(this).css({'cursor': 'w-resize'});
                        }).mousedown(function(e){
                            var $this = $(this);
                            var doc = document;

                            if(e.ctrlKey){
                                loop_state_switch(0);
                            }else{
                                loop_update($this, {left:e.pageX});

                                doc.onmousemove = function(e){
                                    loop_update($this, {left:e.pageX});
                                    let time = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text();
                                    $this.find('.bilibili-player-video-progress-detail-time').text(time);
                                };

                                doc.onmouseup = function(e){
                                    //清除事件
                                    doc.onmousemove=null;
                                    doc.onmouseup=null;
                                    //hide_loop_time();

                                    let time = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text();
                                    $this.find('.bilibili-player-video-progress-detail-time').text(time);

                                    //$this.find('.bilibili-player-video-progress-detail-container').show();

                                    $('#hhh_loop_wrap')[0].hhh_loop_playback_click = $this[0].id;
                                    return false;
                                }
                            }
                        });

                        //监听视频窗口大小变化
                        var ro = new ResizeObserver( entries => {
                            for (let entry of entries) {
                                //更新loop位置
                                resize_updata();
                            }
                        });

                        // Observe one or multiple elements
                        //squirtle-video-time-now 2.X   bilibili-player-video-time-now 3.X
                        ro.observe($('.bilibili-player-video-wrap')[0]);
                    }

                    return false;
                }else{
                    this.hhh_loop_playback_click = false;
                }
            });

            //保存sign原color
            $('.bilibili-player-video-progress-slider')[0].hhh_sign_color = $('.bilibili-player-video-progress-detail-sign-down').css('border-top-color');

            //键盘 down
            $(document).off('keydown.hhh_progress');
            $(document).on('keydown.hhh_progress',function(e){
                if(e.keyCode === keycode['Ctrl']) {
                    if($('.bilibili-player-video-progress').hasClass('bilibili-player-show') === true){
                        $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign-down').css('border-top-color', '#FFA500');
                        $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign-up').css('border-bottom-color', '#FFA500');
                        show_loop_time('sign_show');
                    }
                } else if(e.keyCode === keycode['left'] || e.keyCode === keycode['right']){  //段落循环
                    if($('#hhh_loop_wrap')[0].hhh_loop_playback_click !== false && $('#hhh_loop_1').css('display') !== 'none'){
                        $('.bilibili-player-area').addClass('video-control-show');
                        let $hhh_loop = $('#'+$('#hhh_loop_wrap')[0].hhh_loop_playback_click);
                        let old_seconds = $hhh_loop[0].hhh_seconds;
                        let time1 = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text();
                        let seconds = e.keyCode === keycode['right']? ++$hhh_loop[0].hhh_seconds: --$hhh_loop[0].hhh_seconds;
                        loop_update($hhh_loop, {seconds:seconds});
                        let time2 = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text();
                        if(time1 !== time2) {
                            $hhh_loop.find('.bilibili-player-video-progress-detail-time').text(time2)
                        }else{
                            $hhh_loop[0].hhh_seconds = old_seconds;
                        }
                        return false;
                    }
                }else if(e.keyCode === 'L'.charCodeAt()){
                    if($('#hhh_loop_1')[0].hhh_seconds !== undefined){
                        $('.bilibili-player-area').addClass('video-control-show');
                        $('#hhh_loop_wrap')[0].hhh_loop_state_switch = ++$('#hhh_loop_wrap')[0].hhh_loop_state_switch % 3;
                        loop_state_switch($('#hhh_loop_wrap')[0].hhh_loop_state_switch);
                    }
                }
            });

            //键盘 up
            $(document).off('keyup.hhh_progress');
            $(document).on('keyup.hhh_progress',function(e){
                if(e.keyCode === keycode['Ctrl']) {
                    //if($('.bilibili-player-video-progress').hasClass('bilibili-player-show') === true){
                        $('.bilibili-player-video-progress-detail-sign-down').css('border-top-color', $('.bilibili-player-video-progress-slider')[0].hhh_sign_color);
                        $('.bilibili-player-video-progress-detail-sign-up').css('border-bottom-color', $('.bilibili-player-video-progress-slider')[0].hhh_sign_color);
                        hide_loop_time();
                    //}
                } else if(e.keyCode === keycode['left'] || e.keyCode === keycode['right']){  //段落循环
                    if($('#hhh_loop_wrap')[0].hhh_loop_playback_click !== false){
                        //hide_loop_time();
                        return false;
                    }
                }
            });

            //显示提示
            // function showHint_(parent, selector_str){
            //     //$(`${selector_str}>${bb['volumeHintText']}`).text(text);  //百分比显示
            //     var Hint = $(selector_str);  //显示及渐隐效果(抄bilibili^^)
            //     clearTimeout(parent.showHintTimer),
            //     Hint.stop().css("opacity", 1).show(),
            //     parent.showHintTimer = window.setTimeout((function() {
            //         Hint.animate({
            //             opacity: 0
            //         }, 300, (function() {
            //             hide_loop_time();
            //         }))
            //     }), 1e3)
            // }
        }

        //增加当前在线视频预览
        function run_preview(){
            if($('#hhh_online_list_style').length === 1) return;

            function hide(parent, selector, show_or_hide){
                var o = $();
                if($.isArray(selector) === true){
                    $.each(selector, function(i,v){
                        o = o.add(v);
                    })
                }else{
                    o = $(selector);
                }
                //显示及渐隐效果(抄bilibili^^)
                clearTimeout(parent.showHintTimer),
                    o.stop().show(),
                    parent.showHintTimer = window.setTimeout((function() {
                        o.animate({
                            opacity: 0
                        }, 600, (function() {
                            $(this).hide()
                        }))
                    }
                ), 0)
            }
            function show(parent, selector, show_or_hide){
                var o = $();
                if($.isArray(selector) === true){
                    $.each(selector, function(i,v){
                        o = o.add(v);
                    })
                }else{
                    o = $(selector);
                }
                //显示及渐隐效果(抄bilibili^^)
                clearTimeout(parent.showHintTimer),
                    parent.showHintTimer = window.setTimeout((function() {
                        o.stop().show(),
                        o.animate({
                            opacity: 1
                        }, 600, (function() {
                            $(this).show()
                        }))
                    }
                ), 300)
            }
            if($('#hhh_online_list_style').length<1){
                $('.online-list').append(`<style id="hhh_online_list_style" type="text/css">
                    .hhh-preview-bg {
                        top: 13px;  //硬编码
                        z-index: 2;
                        height: 100%;
                    }
                    .hhh-preview-wrapper {
                        top: 0;
                        z-index: 4;
                        padding: 0 5px 5px;
                        box-sizing: border-box;
                        background-color: #000;
                    }
                    .hhh-preview-bg, .hhh-preview-wrapper {
                        position: absolute;
                        display: none;
                        left: 0;
                        width: 100%;
                    }
                    .hhh-preview-progress {
                        width: 100%;
                        height: 2px;
                        margin-top: 5px;
                        background-color: hsla(0,0%,100%,.4);
                        border-radius: 1px;
                    }
                    .hhh-preview-progress-bar {
                        width: 0;
                        height: 2px;
                        border-radius: 1px;
                        background-color: #fff;
                    }
                    </style>`);
            }
            var bvs = {},
                box_width = 0,
                bg_img_row = 0,
                bg_y_block_len = 0,
                bg_img_totle = 0;
            $('.online-list>.ebox>a>div').mouseenter(function(e){
                this.state = 'enter';
                let $lazy_img = $(this);
                let bvid = $lazy_img.parent().attr('href').match(/BV\w+$/);
                bvid = bvid && bvid[0];
                this.bvid = bvid;
                if(bvs[bvid] === undefined){
                    bvs[bvid] = $lazy_img.parent().attr('title');
                    $.getJSON("https://api.bilibili.com/x/player/videoshot", { bvid: bvid, index: "1" },
                        function(json){
                            let bg_img = json.data.image[0];
                            box_width = $lazy_img.width();
                            bg_img_totle = json.data.index.length > (json.data.img_x_len*json.data.img_x_len)? (json.data.img_x_len*json.data.img_x_len): json.data.index.length;
                            bg_img_row = bg_img_totle < json.data.img_x_len? bg_img_totle: json.data.img_x_len;
                            bg_y_block_len = json.data.img_y_size/json.data.img_x_size*box_width;
                            bvs[bvid] = {box_width:box_width, bg_img_totle:bg_img_totle, bg_img_row:bg_img_row, bg_y_block_len:bg_y_block_len};

                            //log(bg_img_row+' - '+bg_img_totle+' - '+bg_y_block_len);
                            //log(bvs[bvid]);
                            $lazy_img.css({'overflow':'hidden', 'position':'relative'});
                            $lazy_img.append(`<div class="hhh-preview-bg" style="background-position: 0px 0px; background-size: ${box_width*bg_img_row}px; background-image: url('${bg_img}');"></div>
                                              <div class="hhh-preview-wrapper" style="display: none; opacity: 1;"><div class="hhh-preview-progress"><div class="hhh-preview-progress-bar" style="width: 50%;"></div></div></div>`);
                            if($lazy_img[0].state === 'enter') show($lazy_img[0], [$lazy_img.find('.hhh-preview-bg'), $lazy_img.find('.hhh-preview-wrapper')], 'show');
                    });
                }else{
                    show($lazy_img[0], [$lazy_img.find('.hhh-preview-bg'), $lazy_img.find('.hhh-preview-wrapper')], 'show');
                }
            }).mouseleave(function(){
                this.state = 'leave';
                hide(this, [$(this).find('.hhh-preview-bg'), $(this).find('.hhh-preview-wrapper')], 'hide');
            }).mousemove(function(e){
                //log(this.bvid);
                let obv = bvs[this.bvid];
                let amounts = Math.floor(e.offsetX/(obv.box_width/obv.bg_img_totle));
                let x =  Math.floor(amounts % obv.bg_img_row) * -obv.box_width;
                x = Math.min(Math.max(x,-obv.box_width*(obv.bg_img_totle-1)),0);
                let y =  Math.floor(amounts/obv.bg_img_row) * -obv.bg_y_block_len;
                //log('---'+box_width+' - '+bg_img_totle);
                //log(e.offsetX+' - '+amounts+' - '+x+' - '+y+' - '+bg_y_block_len+' - '+Math.floor(amounts/bg_img_row));
                $(this).find('.hhh-preview-bg').css({'background-position':`${x}px ${y}px`});

                let w = Math.round(e.offsetX/obv.box_width*100);
                $(this).find('.hhh-preview-progress-bar').css({'width':`${w}%`});
            })
        }

        //动态首页直接显示隐藏content
        function run_content(){
            if($('[hhh_has_content]').length < $('.video-container').length){
                $('.video-container').each(function(){
                    let $container = $(this);
                    let $hhh_has_content = $container.find('[hhh_has_content]');
                    if($hhh_has_content.length >= 1) return true;

                    //显示隐藏标题
                    let $title = $container.find('.title');
                    let line_height = $title.css('line-height');
                    let font_size = $title.css('font-size');
                    let h = $title.removeClass('title').css({'line-height':line_height, 'font-size':font_size}).height();
                    line_height = line_height.match(/\d+/)[0];
                    $title.addClass('title');
                    if(h > line_height*2){
                        $title.attr('title', $title.text())
                    }

                    //显示隐藏content
                    let $content = $container.find('.content');
                    //console.log($content.text().slice(0,10)+ ' : ' +$content.height());
                    line_height = $content.css('line-height');
                    //log($content.height());
                    font_size = $content.css('font-size');
                    h = $content.removeClass('content').css({'line-height':line_height, 'font-size':font_size}).height();
                    line_height = line_height.match(/\d+/)[0];
                    //console.log('---line_h:'+line_height+'  h: '+h+'  title: '+$container.find('.title').text());
                    $content.addClass('content');
                    $content.attr('hhh_has_content', true);

                    if(h > line_height*2){
                        //console.log(line_height*2);
                        $content.height(line_height);
                        let $expand = $(`<div style="color:#178bcf; font-size:12px; line-height:22px; display:block" onMouseOver="this.style.color='#00b5e5'" onMouseOut="this.style.color='#178bcf'">展开</div>`).insertAfter($content);
                        //let $expand = $(`<div class="expand-btn" data-v-98357e68 style="font-size:12px; line-height:22px; display:block" onMouseOver="this.style.color='#00b5e5'" onMouseOut="this.style.color='#178bcf'">展开</div>`).insertAfter($content);
                        $expand.add($content).click(function(){
                            if($expand.text() === '展开'){
                                //console.log('=='+$content.height()+'==='+$content.css('line-height').match(/\d+/)[0]);
                                $container.height('auto');
                                $content.css({height:'auto', 'max-height':'none', '-webkit-box-orient':'inline-axis', 'margin-top':'0px', 'padding-top':'8px'});
                                $expand.text('收起');
                            }else{
                                $content.height(line_height);
                                $content.css({'-webkit-box-orient':'vertical'});
                                $expand.text('展开');
                            }
                            return false
                        });
                    }
                })
            }
        }

        //初始化
        function init() {
            console.clear();
            var is_card_load = false;
            new MutationObserver((mutations, observer) => {
                mutations.forEach(mutation => {
                    const target = mutation.target;
                    //typeof target.className === 'string' && target.className !== '' && log(target.className);
                    const stage = mutation.previousSibling && target.getAttribute('stage');
                    if(stage === '1' && $('.bilibili-player-video-wrap').length === 1){  //2.X
                        if($('#app').hasClass('app-v1')){
                            log("2.X“V3版”加载完毕");
                            bb_config.set_bb(BILI_2_X_V3);
                            run();
                        }else{
                            log("2.X“V2版”加载完毕");
                            bb_config.set_bb(BILI_2_X_V2);
                            run();
                        }
                    } else if(typeof target.className === 'string' && target.className === 'squirtle-fullscreen-wrap squirtle-block-wrap' && $('.bpx-player-video-area').length === 1) {  //3.X  pbp-tip
                        log("3.X加载完毕");
                        bb_config.set_bb(BILI_3_X);
                        run();
                    } else if(typeof target.className === 'string' && target.className==='card'){
                        //log($('.video-container .expand-btn').length+'   '+$('.video-container .content').length +'content_count: '+content_count);
                        //log('video-container: '+$('.video-container .content').length +'      content_count: '+content_count+'   [hhh_has_content]: '+$('[hhh_has_content]').length);
                        //if(target.className==='loading-content bg-white') content_count = 0;
                        log("2.X动态首页加载完毕");
                        run_content();
                    } else if(typeof target.className === 'string' && target.className === 'avatar' && target.baseURI.indexOf('www.bilibili.com/video/online.html') !== -1){
                        //log($('#hhh_online_list_style').length);
                        log("当前在线加载完毕");
                        run_preview();
                    //} else if(typeof target.className === 'string' && target.className==='player-auxiliary'){
                        //log($('.player-auxiliary-filter-wrap.player-auxiliary-danmaku').length);
                    // } else if(is_card_load === false && typeof target.className === 'string' && target.className === 'card' && $(target).find('.video-container .content').length){
                        // is_card_load = true;
                        // log("2.X动态首页加载完毕");
                        // run_card();  //搞笑,刚写完,2.70.7就有了
                        // removeMostViewedListener(config.getCheckboxSettingStatus('removeMostViewedListener'));
                    }
                });
            }).observe(document.body, {
                childList: true,
                subtree: true,
            });
        }

        init();
    }
}

hhh_lightoff_main.init();