A Universal Script to Re-Enable the Selection and Copying

Enables select, right-click, copy and drag on pages that disable them. Enhanced Feature: Alt Key HyperLink Text Selection

Tính đến 23-06-2021. Xem phiên bản mới nhất.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

Bạn sẽ cần cài đặt một tiện ích mở rộng như Tampermonkey hoặc Violentmonkey để cài đặt kịch bản này.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(Tôi đã có Trình quản lý tập lệnh người dùng, hãy cài đặt nó!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         A Universal Script to Re-Enable the Selection and Copying
// @name:zh-TW   A Universal Script to Re-Enable the Selection and Copying
// @version      1.7.8.16
// @description  Enables select, right-click, copy and drag on pages that disable them. Enhanced Feature: Alt Key HyperLink Text Selection
// @description:zh-TW 解除禁止復制、剪切、選擇文本、右鍵菜單的限制。破解鎖右鍵、文字複製、文字選取。增強功能:Alt鍵超連結文字選取。
// @include      /^https?\:\/\//
// @grant        none
// @run-at       document-start
// @namespace https://greatest.deepsurf.us/users/371179
// ==/UserScript==
(function $$() {
    'use strict';
    if (document == null || !document.documentElement) return window.requestAnimationFrame($$); // this is tampermonkey bug?? not sure
    //console.log('script at', location)

    function $nil() {}

    function isSupportAdvancedEventListener() {
        if ('_b1750' in $) return $._b1750
        var prop = 0;
        document.createAttribute('z').addEventListener('nil', $nil, {
            get passive() {
                prop++;
            },
            get once() {
                prop++;
            }
        });
        return ($._b1750 = prop == 2);
    }

    function isSupportPassiveEventListener() {
        if ('_b1650' in $) return $._b1650
        var prop = 0;
        document.createAttribute('z').addEventListener('nil', $nil, {
            get passive() {
                prop++;
            }
        });
        return ($._b1650 = prop == 1);
    }

    var getSelection = window.getSelection || Error()(),
        requestAnimationFrame = window.requestAnimationFrame || Error()(),
        getComputedStyle = window.getComputedStyle || Error()();

    const $ = {
        utSelectionColorHack: 'msmtwejkzrqa',
        utTapHighlight: 'xfcklblvkjsj',
        utLpSelection: 'gykqyzwufxpz',
        utHoverBlock: 'meefgeibrtqx', //scc_emptyblock
        ksFuncReplacerNonFalse: '___dqzadwpujtct___',
        ksEventReturnValue: ' ___ndjfujndrlsx___',
        ksSetData: '___rgqclrdllmhr___',

        eh_capture_passive: () => isSupportPassiveEventListener() ? ($._eh_capture_passive = ($._eh_capture_passive || {
            capture: true,
            passive: true
        })) : true,

        mAlert_DOWN: function() {}, //dummy function in case alert replacement is not valid
        mAlert_UP: function() {}, //dummy function in case alert replacement is not valid

        isAnySelection: function() {
            var sel = getSelection();
            return !sel ? null : (typeof sel.isCollapsed == 'boolean') ? !sel.isCollapsed : (sel.toString().length > 0);
        },

        createCSSElement: function(cssStyle, container) {
            var css = document.createElement('style'); //slope: DOM throughout
            css.type = 'text/css';
            css.innerHTML = cssStyle;
            if (container) container.appendChild(css);
            return css;
        },

        createFakeAlert: function(_alert) {
            if (typeof _alert != 'function') return null;

            function alert(msg) {
                alert.__isDisabled__() ? console.log("alert msg disabled: ", msg) : _alert.apply(this, arguments);
            };
            alert.toString = () => "function alert() { [native code] }";
            return alert;
        },

        createFuncReplacer: function(originalFunc, pName, resFX) {
            resFX = function(ev) {
                var res = originalFunc.apply(this, arguments);
                if (!this || this[pName] != resFX) return res; // if this is null or undefined, or this.onXXX is not this function
                if (res === false) return; // return undefined when "return false;"
                originalFunc[$.ksFuncReplacerNonFalse] = true;
                this[pName] = originalFunc; // restore original
                return res;
            }
            resFX.toString = () => originalFunc.toString();
            return resFX;
        },

        listenerDisableAll: function(evt) {
            var elmNode = evt.target;
            var pName = 'on' + evt.type;
            evt = null;
            Promise.resolve().then(() => {
                while (elmNode && elmNode.nodeType > 0) { //i.e. HTMLDocument or HTMLElement
                    var f = elmNode[pName];
                    if (typeof f == 'function' && f[$.ksFuncReplacerNonFalse] !== true) {
                        var nf = $.createFuncReplacer(f, pName);
                        nf[$.ksFuncReplacerNonFalse] = true;
                        elmNode[pName] = nf;
                    }
                    elmNode = elmNode.parentNode;
                }
            })
        },

        onceCssHighlightSelection: () => {
            if (document.documentElement.hasAttribute($.utLpSelection)) return;
            $.onceCssHighlightSelection = null
            Promise.resolve().then(() => {
                var s = [...document.querySelectorAll('a,p,div,span,b,i,strong,li')].filter(elm => elm.childElementCount === 0); // randomly pick an element containing text only to avoid css style bug
                var elm = !s.length ? document.body : s[s.length >> 1];
                return elm
            }).then(elm => {
                var selectionStyle = getComputedStyle(elm, ':selection');
                if (/^rgba\(\d+,\s*\d+,\s*\d+,\s*0\)$/.test(selectionStyle.getPropertyValue('background-color'))) document.documentElement.setAttribute($.utSelectionColorHack, "");
                return elm;
            }).then(elm => {
                var elmStyle = getComputedStyle(elm)
                if (/^rgba\(\d+,\s*\d+,\s*\d+,\s*0\)$/.test(elmStyle.getPropertyValue('-webkit-tap-highlight-color'))) document.documentElement.setAttribute($.utTapHighlight, "");
            })
        },

        isCurrentClipboardDataReplaced: function(clipboardData) {
            var items = clipboardData ? clipboardData.items : null;
            if (items && items.length > 0) {
                for (var i = 0, l = items.length; i < l; i++) {
                    if (items[i].type == 'text/plain') return true;
                }
            }
            return false;
        },

        replacementSetData: function(_setData, evt) {
            if (typeof _setData != 'function') return;

            function setData() {
                var res = _setData.apply(this, arguments);
                try {
                    if (evt.clipboardData === this && this.setData === setData && evt.cancelable && evt.defaultPrevented === false) {
                        if ($.isCurrentClipboardDataReplaced(evt.clipboardData)) {
                            evt.preventDefault();
                            if (evt.defaultPrevented === true) {
                                this.setData = _setData;
                                delete this[$.ksSetData];
                            }
                        }
                    }
                } catch (e) {}
                return res;
            }
            setData.toString = () => _setData.toString();
            evt.clipboardData.setData = setData;
            evt.clipboardData[$.ksSetData] = _setData;
        },


        enableSelectClickCopy: function() {
            $.eyEvts = ['keydown', 'keyup', 'copy', 'contextmenu', 'select', 'selectstart', 'dragstart', 'beforecopy']; //slope: throughout

            function isDeactivePreventDefault(evt) {
                if ($.bypass) return false;
                var j = $.eyEvts.indexOf(evt.type);
                switch (j) {
                    case 6:
                        if ($.enableDragging) return false;
                        if (evt.target.hasAttribute('draggable')) {
                            $.enableDragging = true;
                            return false;
                        }
                        //if(evt.target.hasAttribute('draggable')&&evt.target!=window.getSelection().anchorNode)return false;
                        return true;
                    case 3:
                        if (evt.target instanceof Element && (evt.target.textContent || "").trim().length === 0) return false; //exclude elements like video
                        return true;
                    case -1:
                        return false;
                    case 0:
                    case 1:
                        return (evt.keyCode == 67 && (evt.ctrlKey || evt.metaKey) && !evt.altKey && !evt.shiftKey && $.isAnySelection() === true);
                    case 2:

                        if (!('clipboardData' in evt && 'setData' in DataTransfer.prototype)) return true; // Event oncopy not supporting clipboardData
                        // see the richtext hack in https://www.cleancss.com/css-beautify/
                        // see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/copy_event
                        // see https://w3c.github.io/clipboard-apis/#widl-ClipboardEvent-clipboardData

                        if ($.isCurrentClipboardDataReplaced(evt.clipboardData) == false) { //no replacement data
                            if (!evt.clipboardData[$.ksSetData] && evt.cancelable && evt.defaultPrevented === false) $.replacementSetData(evt.clipboardData.setData, evt);
                            return true;
                        }
                        var trimedSelectionText = getSelection().toString().trim()
                        if (trimedSelectionText) {
                            //there is replacement data and the selection is not empty
                            console.log("copy event - clipboardData replacement is allowed and the selection is not empty", trimedSelectionText)
                            return false;
                        } else {
                            //there is replacement data and the selection is empty
                            return false;
                        }
                        break; // for js formatting only

                    default:
                        return true;
                }
            }

            Event.prototype.preventDefault = (function(f) {
                function preventDefault() {
                    if (!isDeactivePreventDefault(this)) f.call(this);
                }
                preventDefault.toString = () => f.toString();
                return preventDefault;
            })(Event.prototype.preventDefault);

            Object.defineProperty(Event.prototype, "returnValue", {
                get() {
                    return $.ksEventReturnValue in this ? this[$.ksEventReturnValue] : true;
                },
                set(newValue) {
                    if (newValue === false && !isDeactivePreventDefault(this)) this.preventDefault();
                    this[$.ksEventReturnValue] = newValue;
                },
                enumerable: true,
                configurable: true
            });

            for (var i = 2, eventsCount = $.eyEvts.length; i < eventsCount; i++) {
                document.addEventListener($.eyEvts[i], $.listenerDisableAll, true); // Capture Event; passive:false; expected occurrence COMPLETELY before Target Capture and Target Bubble
            }

            var _alert = window.alert; //slope: temporary
            if (typeof _alert == 'function') {
                var _mAlert = $.createFakeAlert(_alert);
                if (_mAlert) {
                    var clickBlockingTo = 0;
                    _mAlert.__isDisabled__ = () => clickBlockingTo > +new Date;
                    $.mAlert_DOWN = () => (clickBlockingTo = +new Date + 50);
                    $.mAlert_UP = () => (clickBlockingTo = +new Date + 20);
                    window.alert = _mAlert
                }
            }

        },

        lpCheckPointer: function(targetElm) {
            if (targetElm && targetElm.nodeType == 1 && targetElm.matches('*:hover')) {
                if (getComputedStyle(targetElm).getPropertyValue('cursor') == 'pointer' && targetElm.textContent) return true;
            }
            return false;
        },

        lpFullCancel: function(evt, toPreventDefault) {
            $.bypass = true;
            !toPreventDefault || evt.preventDefault()
            evt.stopPropagation();
            evt.stopImmediatePropagation();
            $.bypass = false;
        },

        lpMouseDown: function(evt) {
            $.lpMouseActive = 0;
            if (evt.altKey && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && evt.button === 0 && $.lpCheckPointer(evt.target)) {
                $.lpMouseActive = 1;
                $.lpFullCancel(evt, false);
                document.documentElement.setAttribute($.utLpSelection, '');
            }
        },

        lpMouseUp: function(evt) {
            if ($.lpMouseActive == 1) {
                $.lpMouseActive = 2;
                document.documentElement.removeAttribute($.utLpSelection);
                $.lpFullCancel(evt, false);
                if ($.onceCssHighlightSelection) window.requestAnimationFrame($.onceCssHighlightSelection);
            }
        },

        lpClick: function(evt) {
            if ($.lpMouseActive == 2) {
                $.lpFullCancel(evt, false);
            }
        },

        lpEnable: function() { // this is an optional feature for modern browser
            // the built-in browser feature has already disabled the default event behavior, the coding is just to ensure no "tailor-made behavior" occuring.
            document.addEventListener('mousedown', $.lpMouseDown, {
                capture: true,
                passive: true
            })
            document.addEventListener('mouseup', $.lpMouseUp, {
                capture: true,
                passive: true
            })
            document.addEventListener('click', $.lpClick, {
                capture: true,
                passive: true
            })
        },

        mainEnableScript: () => {
            var cssStyleOnReady = `
            html, html *,
            html *::before, html *::after,
            html *:hover, html *:link, html *:visited, html *:active,
            html *[style], html *[class]{
            -khtml-user-select: auto !important; -moz-user-select: auto !important; -ms-user-select: auto !important;
            -webkit-touch-callout: default !important; -webkit-user-select: auto !important; user-select: auto !important;
            }
            *:hover>img[src]{pointer-events:auto !important;}

            [${$.utSelectionColorHack}] :not(input):not(textarea)::selection{ background-color: Highlight !important; color: HighlightText !important;}
            [${$.utSelectionColorHack}] :not(input):not(textarea)::-moz-selection{ background-color: Highlight !important; color: HighlightText !important;}
            [${$.utTapHighlight}] *{ -webkit-tap-highlight-color: rgba(0, 0, 0, 0.18) !important;}

             html[${$.utLpSelection}] *:hover, html[${$.utLpSelection}] *:hover * { cursor:text !important;}
             html[${$.utLpSelection}] :not(input):not(textarea)::selection {background-color: rgba(255, 156, 179,0.5) !important;}
             html[${$.utLpSelection}] :not(input):not(textarea)::-moz-selection {background-color: rgba(255, 156, 179,0.5) !important;}

             [${$.utHoverBlock}="2"]{pointer-events:none !important;user-select:none !important;}
             img[${$.utHoverBlock}="4"]{
             display:none !important;
             }
[${$.utHoverBlock}="7"]{
padding:0 !important;
}
             [${$.utHoverBlock}="7"]>img[${$.utHoverBlock}="4"]:first-child{
             display:inline-block !important;
             opacity: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    position: relative !important;
    z-index:1 !important;
    width: 100% !important;
    height: 100% !important;
    left: 0 !important;
    top: 0 !important;
    outline: 0 !important;
    border: 0 !important;
    box-sizing: border-box !important;
    transform: initial !important;
    float: left !important;
            pointer-events:auto !important; user-select:none !important;cursor:inherit !important;}

            `.trim();

            $.enableSelectClickCopy()
            $.createCSSElement(cssStyleOnReady, document.documentElement);

        },

        mainEvents: (listenerPress, listenerRelease) => {
            document.addEventListener("mousedown", listenerPress, true); // Capture Event; (desktop)
            document.addEventListener("contextmenu", listenerPress, true); // Capture Event; (desktop&mobile)
            document.addEventListener("mouseup", listenerRelease, false); // Bubble Event;
        },

        disableHoverBlock: () => {

            var nMap = new WeakMap()

            function elmParam(elm) {

                var mElm = nMap.get(elm);
                if (!mElm) nMap.set(elm, mElm = {});
                return mElm;
            }

            function overlapArea(rect1, rect2) {

                let l1 = {
                    x: rect1.left,
                    y: rect1.top
                }

                let r1 = {
                    x: rect1.right,
                    y: rect1.bottom
                }
                let l2 = {
                    x: rect2.left,
                    y: rect2.top
                }

                let r2 = {
                    x: rect2.right,
                    y: rect2.bottom
                }

                // Area of 1st Rectangle
                let area1 = Math.abs(l1.x - r1.x) * Math.abs(l1.y - r1.y);

                // Area of 2nd Rectangle
                let area2 = Math.abs(l2.x - r2.x) * Math.abs(l2.y - r2.y);

                // Length of intersecting part i.e
                // start from max(l1.x, l2.x) of
                // x-coordinate and end at min(r1.x,
                // r2.x) x-coordinate by subtracting
                // start from end we get required
                // lengths
                let x_dist = Math.min(r1.x, r2.x) - Math.max(l1.x, l2.x);
                let y_dist = (Math.min(r1.y, r2.y) - Math.max(l1.y, l2.y));
                let areaI = 0;
                if (x_dist > 0 && y_dist > 0) {
                    areaI = x_dist * y_dist;
                }

                return {
                    area1,
                    area2,
                    areaI
                };


            }

            function redirectEvent(event, toElement) {

                toElement.dispatchEvent(new event.constructor(event.type, event));
                if (event.type != 'wheel') event.preventDefault();
                event.stopPropagation();
            }

            const floatingBlockHover = new WeakMap();

            let _nImgs = [];

            function nImgFunc() {

                for (const s of _nImgs) {
                    if (s.lastTime + 800 < +new Date) {
                        s.lastTime = +new Date;
                        return s.elm
                    }
                }

                let nImg = document.createElement('img');
                nImg.onerror = function() {
                    if (this.parentNode != null) this.parentNode.removeChild(this)
                }
                nImg.setAttribute($.utHoverBlock, '4');
                const handle = function(event) {
                    if (this === event.target) {
                        if (event.button != 2) redirectEvent(event, this.parentNode)
                        Promise.resolve().then(() => {
                            for (const s of _nImgs) {
                                if (s.elm === this) {
                                    s.lastTime = +new Date
                                }
                            }
                        })
                    }
                }
                nImg.addEventListener('click', handle, true);
                nImg.addEventListener('mousedown', handle, true);
                nImg.addEventListener('mouseup', handle, true);
                nImg.addEventListener('mousemove', handle, true);
                nImg.addEventListener('mouseover', handle, true);
                nImg.addEventListener('mouseout', handle, true);
                nImg.addEventListener('mouseenter', handle, true);
                nImg.addEventListener('mouseleave', handle, true);
                //nImg.addEventListener('wheel', handle, $.eh_capture_passive());
                _nImgs.push({
                    elm: nImg,
                    lastTime: +new Date
                })

                return nImg;

            }

            const wmHoverUrl = new WeakMap();
            let lastMouseEnterElm = null;
            let lastMouseEnterAt = 0;
            let lastMouseEnterCid = 0;

            function mouseEnter() {
                lastMouseEnterCid = 0;

                if (+new Date - lastMouseEnterAt < 30) {
                    lastMouseEnterCid = setTimeout(mouseEnter, 82)
                    return;
                }

                const targetElm = lastMouseEnterElm

                Promise.resolve()
                    .then(() => {
                        if (targetElm && targetElm.parentNode) {} else {
                            return;
                        }
                        if (floatingBlockHover.get(targetElm)) {
                            let url = null
                            if (targetElm.getAttribute($.utHoverBlock) == '7' && (url = wmHoverUrl.get(targetElm)) && targetElm.querySelector(`[${$.utHoverBlock}]`) == null) {
                                let _nImg = nImgFunc();
                                if (_nImg.parentNode !== targetElm) {
                                    _nImg.setAttribute('src', url);
                                    targetElm.insertBefore(_nImg, targetElm.firstChild);
                                }
                            }
                            return;
                        }
                        floatingBlockHover.set(targetElm, 1);
                        return 1;
                    }).then((ayRes) => {
                        if (!ayRes) return;

                        if (targetElm.nodeType != 1) return;
                        if ("|SVG|IMG|HTML|BODY|VIDEO|AUDIO|BR|HEAD|NOSCRIPT|SCRIPT|STYLE|TEXTAREA|AREA|INPUT|FORM|BUTTON|".indexOf(`|${targetElm.nodeName}|`) >= 0) return;

                        const targetArea = targetElm.clientWidth * targetElm.clientHeight

                        if (targetArea > 0) {} else {
                            return;
                        }

                        const targetCSS = getComputedStyle(targetElm)
                        const targetBgImage = targetCSS.getPropertyValue('background-image');
                        let exec1 = null

                        if (targetBgImage != 'none' && (exec1 = /^\s*url\s*\("?([^"\)]+\b(\.gif|\.png|\.jpeg|\.jpg|\.webp)\b[^"\)]*)"?\)\s*$/i.exec(targetBgImage))) {
                            if ((targetElm.textContent || "").trim().length > 0) return;
                            const url = exec1[1];
                            return url

                            // console.log(targetBgImage,[...exec1])
                        }



                        if (targetCSS.getPropertyValue('position') == 'absolute' && +targetCSS.getPropertyValue('z-index') > 0) {} else {
                            return;
                        }
                        if ((targetElm.textContent || "").trim().length > 0) return;

                        let possibleResults = [];

                        for (const imgElm of document.querySelectorAll('img[src]')) {
                            const param = elmParam(imgElm)
                            if (!param.area) {
                                const area = imgElm.clientWidth * imgElm.clientHeight
                                if (area > 0) param.area = area;
                            }
                            if (param.area > 0) {
                                if (targetArea > param.area * 0.9) possibleResults.push(imgElm)
                            }
                        }

                        let i = 0;
                        let j = 0;
                        for (const imgElm of possibleResults) {

                            const cmpVal = targetElm.compareDocumentPosition(imgElm)

                            /*


1: The two nodes do not belong to the same document.
2: p1 is positioned after p2.
4: p1 is positioned before p2.
8: p1 is positioned inside p2.
16: p2 is positioned inside p1.
32: The two nodes has no relationship, or they are two attributes on the same element.

            */

                            if (cmpVal & 8 || cmpVal & 16) return;
                            if (cmpVal & 2) j++; // I<p
                            else if (cmpVal & 4) break; // I>p


                            i++;

                        }

                        // before: j-1  after: j

                        let indexBefore = j - 1;
                        let indexAfter = j;
                        if (indexBefore < 0) indexBefore = 0;
                        if (indexAfter > possibleResults.length - 1) indexAfter = possibleResults.length - 1;

                        //    setTimeout(function(){
                        for (let i = indexBefore; i <= indexAfter; i++) {
                            const s = possibleResults[i];
                            const {
                                area1,
                                area2,
                                areaI
                            } = overlapArea(targetElm.getBoundingClientRect(), s.getBoundingClientRect())
                            const criteria = area1 * 0.7
                            if (areaI > 0.9 * area2) {


                                return s.getAttribute('src')


                            }
                        }
                        //   },1000);

                    }).then((sUrl) => {

                        if (typeof sUrl != 'string') return;


                        // console.log(313, evt.target, s)
                        let _nImg = nImgFunc();


                        if (_nImg.parentNode !== targetElm) {
                            _nImg.setAttribute('src', sUrl);
                            targetElm.insertBefore(_nImg, targetElm.firstChild);
                            wmHoverUrl.set(targetElm, sUrl);
                            targetElm.setAttribute($.utHoverBlock, '7');
                        }



                    })

            }

            document.addEventListener('mouseenter', function(evt) {
                lastMouseEnterElm = evt.target
                lastMouseEnterAt = +new Date;
                if (!lastMouseEnterCid) lastMouseEnterCid = setTimeout(mouseEnter, 82)
            }, $.eh_capture_passive())



        }

    }
/*
    document.addEventListener('selectstart', function(e) {
        if (!e || !e.target) return;
        if (e.target.nodeType > 0) {} else {
            return;
        }
        switch (e.target.nodeName) {
            case 'BUTTON':
            case 'INPUT':
            case 'TEXTAREA':
            case 'FORM':
            case 'BODY':
            case 'HTML':
            case 'HEAD':
            case 'SCRIPT':
            case 'IMG':
            case 'A':
            case 'BR':
            case 'I':
            case 'STRONG':
                return;
        }
        if(e.target && e.cancelable && e.isTrusted && e.target.childElementCount===0){
        console.log(3434,e.target)
            if(e.target === $.holdingElm && (e.target.textContent || "").trim().length === 0) {
            console.log(e, e.target, e.target.childElementCount)
            console.log(1212)
            $.bypass = true;
            e.preventDefault();
            $.bypass = false;
        }
        }
    }, true)*/

   // $.holdingElm=null;

    $.mainEnableScript();

    if (isSupportAdvancedEventListener()) $.lpEnable(); // top capture event for alt-click

    $.mainEvents(
        function(evt) {
         //   $.holdingElm=evt.target;
         //   console.log('down',evt.target)
            if ($.onceCssHighlightSelection) window.requestAnimationFrame($.onceCssHighlightSelection);
            if (evt.button == 2 || evt.type == "contextmenu") $.mAlert_DOWN();
        },
        function(evt) {
          //  $.holdingElm=null;
         //   console.log('up',evt.target)
            if (evt.button == 2) $.mAlert_UP();
            if ($.enableDragging) {
                $.enableDragging = false;
            }
        }
    );

    $.disableHoverBlock();

    console.log('userscript running - To Re-Enable Selection & Copying');




})();