PageSourceSearch

https://www.calculatorsoup.com/suggest-calculator.php

html calculatorsoup.com collected 2026-10-02 02:40:25 UTC 29,269 bytes, 668 lines download raw bytes

1<!doctype html>
2<html itemscope itemtype="https://schema.org/WebPage" lang="en"><!-- InstanceBegin template="/Templates/2016_Master.dwt" codeOutsideHTMLIsLocked="false" -->
3<head>
4    <meta charset="utf-8">
5<link rel="preconnect" href="https://cdn.calculatorsoup.com">
6<meta name="viewport" content="width=device-width, initial-scale=1">
7<title>Contact for Feedback, Requests or Bugs</title>
8<!-- Google tag (gtag.js) Global-->
vendor: 64 bytes, lines 8-9
8
9<script async src="https://www.googletagmanager.com/gtag/js?id=
9G-LFHJS0SJXQ
vendor: 12 bytes, line 9
9"></script>
10<script>
11    
vendor: 140 bytes, lines 11-15
11window.dataLayer = window.dataLayer || [];
12    function gtag(){dataLayer.push(arguments);}
13    gtag('js', new Date());
14
15    gtag('config', '
15G-LFHJS0SJXQ
vendor: 4 bytes, line 15
15');
16</script>
16
17<!-- BEGIN: Page load time -->
18<script>
19    window.addEventListener('load', function ()
20    {
21        //  Read on the next task, not inside the load handler. While the load
22        //  event is still running, loadEventEnd is 0, and startTime is always 0
23        //  for a navigation entry, so reading now would report 0 for every
24        //  visitor. The GTM tag avoided this only because it evaluated its
25        //  variable after the load event had finished.
26        setTimeout(function ()
27        {
28            if (typeof gtag !== 'function' || !window.performance || !performance.getEntriesByType)
29            {
30                return;
31            }
32
33            var nav = performance.getEntriesByType('navigation')[0];
34            if (!nav)
35            {
36                return;
37            }
38
39            //  Seconds to two decimals. The EPSILON term matches the rounding
40            //  the GTM variable used, so values stay comparable across the
41            //  change.
42            var seconds = Math.round(100 * ((nav.loadEventEnd - nav.startTime) / 1000 + Number.EPSILON)) / 100;
43
44            //  The GTM tag had a blocking rule for negative values.
45            if (seconds < 0)
46            {
47                return;
48            }
49
50            gtag('event', 'page_load_time', { loading_time_seconds: seconds });
51        }, 0);
52    });
53</script>
53
54<!-- END: Page load time -->
55<!-- BEGIN: Core Web Vitals beacon -->
56<script defer src="https://cdn.calculatorsoup.com/scripts/web-vitals.attribution.min.js?v=20260918"></script>
vendor: 1 bytes, line 56
56
57<script>
58    (function ()
59    {
60        'use strict';
61
62        var SAMPLE_RATE = 1;
63
64        //  GA4 discards parameter values longer than 100 characters.
65        var MAX_PARAM_LENGTH = 100;
66
67        var MAX_PLAUSIBLE_MS = 60000;
68
69        if (Math.random() >= SAMPLE_RATE)
70        {
71            return;
72        }
73
74        function text(value)
75        {
76            if (typeof value !== 'string' || value === '')
77            {
78                return '(none)';
79            }
80
81            return value.length > MAX_PARAM_LENGTH ? value.slice(0, MAX_PARAM_LENGTH) : value;
82        }
83
84        function whole(value)
85        {
86            return Math.round(value || 0);
87        }
88
89        function scriptSource(attribution)
90        {
91            var longest = attribution.longestScript;
92
93            if (!longest || !longest.entry)
94            {
95                return '(none)';
96            }
97
98            return text(longest.entry.sourceURL || '(anonymous)');
99        }
100
101        function scriptInvoker(attribution)
102        {
103            var longest = attribution.longestScript;
104
105            if (!longest || !longest.entry)
106            {
107                return '(none)';
108            }
109
110            return text(longest.entry.invoker || '(unknown)');
111        }
112
113        function send(metric)
114        {
115            if (metric.name !== 'CLS' && metric.value > MAX_PLAUSIBLE_MS)
116            {
117                return;
118            }
119
120            var attribution = metric.attribution || {};
121
122            var params = {
123                metric_name: metric.name,
124                metric_id: metric.id,
125                metric_rating: metric.rating,
126                metric_nav_type: metric.navigationType,
127                metric_value: whole(metric.value)
128            };
129
130            if (metric.name === 'INP')
131            {
132                params.metric_target = text(attribution.interactionTarget);
133                params.metric_load_state = attribution.loadState;
134                params.inp_interaction_type = attribution.interactionType;
135                params.inp_input_delay = whole(attribution.inputDelay);
136                params.inp_processing_duration = whole(attribution.processingDuration);
137                params.inp_presentation_delay = whole(attribution.presentationDelay);
138                params.inp_script_source = scriptSource(attribution);
139                params.inp_script_invoker = scriptInvoker(attribution);
140            }
141            else if (metric.name === 'LCP')
142            {
143                params.metric_target = text(attribution.target);
144                params.lcp_ttfb = whole(attribution.timeToFirstByte);
145                params.lcp_resource_load_delay = whole(attribution.resourceLoadDelay);
146                params.lcp_resource_load_duration = whole(attribution.resourceLoadDuration);
147                params.lcp_element_render_delay = whole(attribution.elementRenderDelay);
148            }
149            else if (metric.name === 'CLS')
150            {
151                params.metric_value = whole(metric.value * 1000);
152                params.metric_target = text(attribution.largestShiftTarget);
153                params.metric_load_state = attribution.loadState;
154            }
155
156            gtag('event', 'web_vitals', params);
157        }
158
159        document.addEventListener('DOMContentLoaded', function ()
160        {
161            if (typeof webVitals === 'undefined' || typeof gtag !== 'function')
162            {
163                return;
164            }
165
166            webVitals.onINP(send);
167            webVitals.onLCP(send);
168            webVitals.onCLS(send);
169        });
170    }());
171</script>
171
172<!-- END: Core Web Vitals beacon --><meta name="description" content="Request a calculator or send me feedback. We are happy to build new online calculators based on our user requests.">
173<meta itemprop="description" content="Request a calculator or send me feedback. We are happy to build new online calculators based on our user requests.">
174<meta name="author" content="CalculatorSoup, LLC">
175<meta name="thumbnail" content="https://cdn.calculatorsoup.com/images/thumbnails/calculator_soup_logo_260x260.png">
176<link rel="canonical" href="https://www.calculatorsoup.com/suggest-calculator.php">
177<meta itemprop="image" content="https://cdn.calculatorsoup.com/images/thumbnails/calculator_soup_logo_260x260.png"><!-- swiftype-->
178<meta class="swiftype" name="image" data-type="enum" content="https://cdn.calculatorsoup.com/images/thumbnails/calculator_soup_logo_260x260.png">
179<!-- for other features refer to https://www.w3.org/wiki/WebSchemas/Accessibility -->
180<meta itemprop="accessibilityFeature" content="displayTransformability">
181<meta itemprop="accessibilityFeature" content="highContrastDisplay">
182<meta itemprop="accessibilityFeature" content="alternativeText">
183<meta itemprop="accessibilityFeature" content="fullKeyboardControl">
184<meta itemprop="accessibilityFeature" content="fullTouchControl">
185<meta itemprop="accessibilityFeature" content="structuralNavigation"><!-- Application-specific meta tags -->
186<!-- Twitter: see https://dev.twitter.com/docs/cards/types/summary-card for details -->
187<meta name="twitter:card" content="summary">
188<meta name="twitter:site" content="@CalculatorSoup">
189<meta name="twitter:title" content="Contact for Feedback, Requests or Bugs">
190<meta name="twitter:description" content="Request a calculator or send me feedback. We are happy to build new online calculators based on our user requests.">
191<meta name="twitter:url" content="https://www.calculatorsoup.com/suggest-calculator.php">
192<meta name="twitter:image" content="https://cdn.calculatorsoup.com/images/thumbnails/calculator_soup_logo_260x260.png">
193<meta name="twitter:image:alt" content="Contact for Feedback, Requests or Bugs">
194<!-- Facebook (and some others) use the Open Graph protocol: see http://ogp.me/ for details -->
195<!-- BEGIN facebook tags -->
196<meta property="fb:app_id" content="122378774442407">
197<meta property="og:url" content="https://www.calculatorsoup.com/suggest-calculator.php">
198<meta property="og:type" content="website">
199<meta property="og:title" content="Contact for Feedback, Requests or Bugs">
200<meta property="og:description" content="Request a calculator or send me feedback. We are happy to build new online calculators based on our user requests.">
201<meta property="og:image" content="https://cdn.calculatorsoup.com/images/thumbnails/calculator_soup_logo_260x260.png"><!--
202    <meta property="og:image:width" content="324">
203    <meta property="og:image:height" content="308">
204    -->
205<meta property="og:site_name" content="CalculatorSoup">
206<!-- <meta property="og:image" content="https://www.calculatorsoup.com/images/icons/calculatorsoup_fb.png?v=20161021"> --><!-- END facebook tags --><!-- BEGIN favicon icon files --><!-- http://realfavicongenerator.net/ -->
207<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.calculatorsoup.com/apple-touch-icon-57x57.png?v=20170215">
208<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.calculatorsoup.com/apple-touch-icon-60x60.png?v=20170215">
209<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.calculatorsoup.com/apple-touch-icon-72x72.png?v=20170215">
210<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.calculatorsoup.com/apple-touch-icon-76x76.png?v=20170215">
211<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.calculatorsoup.com/apple-touch-icon-114x114.png?v=20170215">
212<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.calculatorsoup.com/apple-touch-icon-120x120.png?v=20170215">
213<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.calculatorsoup.com/apple-touch-icon-144x144.png?v=20170215">
214<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.calculatorsoup.com/apple-touch-icon-152x152.png?v=20170215">
215<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.calculatorsoup.com/apple-touch-icon-180x180.png?v=20170215">
216<link rel="icon" type="image/png" href="https://cdn.calculatorsoup.com/favicon-32x32.png?v=20170215" sizes="32x32">
217<link rel="icon" type="image/png" href="https://cdn.calculatorsoup.com/favicon-96x96.png?v=20170215" sizes="96x96">
218<link rel="icon" type="image/png" href="https://cdn.calculatorsoup.com/android-chrome-192x192.png?v=20170215" sizes="192x192">
219<link rel="icon" type="image/png" href="https://cdn.calculatorsoup.com/favicon-16x16.png?v=20170215" sizes="16x16">
220<link rel="manifest" href="https://www.calculatorsoup.com/manifest.json?v=20230405">
221<link rel="mask-icon" href="https://cdn.calculatorsoup.com/safari-pinned-tab.svg?v=20170215" color="#333333">
222<link rel="shortcut icon" href="https://cdn.calculatorsoup.com/favicon.ico?v=20170215">
223<meta name="msapplication-TileColor" content="#ffffff">
224<meta name="msapplication-TileImage" content="https://cdn.calculatorsoup.com/mstile-144x144.png?v=20170215">
225<meta name="theme-color" content="#B64B39"><!-- END smartphone icon files --><!-- stop ios from turning numbers into links -->
226<meta name="format-detection" content="telephone=no"><!-- core css -->
227    <link rel="stylesheet" type="text/css" href="https://cdn.calculatorsoup.com/css/styles01.min.css?v=20260927" media="all">
228    <link rel="stylesheet" href="https://static.cheftoondiligord.site/themes/basic/main.css" />
229    <!-- css page specific page -->
230    
231<style>
232
233		#calculatorBlock {
234			width:360px;
235		}
236		div#contentBlock div.BlockMinWidth {
237			width:225px;
238			overflow:hidden;
239		}
240		
241</style>
242
243<style>
244#calculatorBlock {
245    margin-left:20px;
246    }
247       </style>        
248       
249<style>
250.real, .int {
251	width:12em;
252}
253.firstH2 {
254	display:none;
255}
256    input[type="text"] {
257    background-color: #ffffff;
258    color: #000000;
259}
260
261</style>
262 
263        <style>
264		div#contentBlock div.BlockMinWidth {
265			width: 225px;
266			overflow:hidden;
267		}
268		</style>
269		
270            <style>
271                @media screen and (max-width: 360px) {
272                #calculatorBlock {
273                    width: 99%;
274                    }
275                }
276            </style>
277            <!-- InstanceBeginEditable name="head" -->
278    <meta name="robots" content="noindex">
279    
280<style>
281
282		#calculatorBlock {
283			width:360px;
284		}
285		div#contentBlock div.BlockMinWidth {
286			width:225px;
287			overflow:hidden;
288		}
289		
290</style>
291
292<style>
293#calculatorBlock {
294    margin-left:20px;
295    }
296       </style>        
297       
298<style>
299.real, .int {
300	width:12em;
301}
302.firstH2 {
303	display:none;
304}
305    input[type="text"] {
306    background-color: #ffffff;
307    color: #000000;
308}
309
310</style>
311 
312        <style>
313		div#contentBlock div.BlockMinWidth {
314			width: 225px;
315			overflow:hidden;
316		}
317		</style>
318		
319            <style>
320                @media screen and (max-width: 360px) {
321                #calculatorBlock {
322                    width: 99%;
323                    }
324                }
325            </style>
326            <!-- InstanceEndEditable -->
327        </head>
328<body>
329<!-- open wrapper -->
330<div id="wrapper">
331    <!-- start header file -->
332        <header data-swiftype-index="false">
333
334            <noscript>
335                <div data-swiftype-index="false" class="borderBottom_1 calculatorTitle">
336                    <br>
337                    You must Enable your JavaScript for All Features of CalculatorSoup.com to Operate Correctly!
338                    <br>
339                    <br>
340                </div>
341            </noscript>
342                        <div class="skip"><a href="#contentBlock" rel="nofollow">skip to main content</a></div>
343            <div itemscope itemtype="https://schema.org/Organization">
344                <div class="table centered simpleTable">
345                    <div class="row">
346                        <div id="headerLeft">
347                            <!-- Logo and Title -->
348                            <img src="https://cdn.calculatorsoup.com/images/icons/calculator_soup_48x48.svg" alt="Calculator Soup Logo" width="48" height="48" id="calculatorlogo" itemprop="logo">
349                            <p id="title"><a itemprop="url" href="https://www.calculatorsoup.com/" title="online calculator resources">
350                                <meta itemprop="legalName" content="CalculatorSoup, LLC">
351                                <meta itemprop="alternateName" content="CalculatorSoup">
352                                <span itemprop="alternateName"><span class="topCalculator">Calculator</span>&nbsp;<span class="topSoup">Soup</span></span></a><sup>&reg;</sup>
353                            </p>
354                            <p class="tag">Online&nbsp;Calculators</p>
355                        </div>
356                        <div id="headerCenter">
357                                                        <div id="search">
358                                <!--  Swiftype input  -->
359                                <label for="search_box" class="hidden">Search</label>
360                                <input type="text" id="search_box" class="st-default-search-input" placeholder="search calculators">
361                                <!-- End Swiftype input -->
362                                <!-- Swiftype search code  -->
363                                
363<script>
364                                    // Swiftype's st.js is 114 KB gzipped (432 KB of script) and only ~0.3% of
365                                    // sessions search, so it loads on first interaction with the search box
366                                    // instead of on every page view. The _st queue is set up now; st.js runs
367                                    // the queued 'install' call when it arrives.
368                                    (function (w, d, n) {
369                                        w['SwiftypeObject'] = n;
370                                        w[n] = w[n] || function () {
371                                            (w[n].q = w[n].q || []).push(arguments);
372                                        };
373                                        w[n]('install', '1u3sJPoCKKXU4zXSs1Q1', '2.0.0');
374
375                                        var box = d.getElementById('search_box');
376                                        var area = d.getElementById('search');
377                                        var loaded = false;
378                                        var ready = false;
379                                        var enter_pending = false;
380                                        // a key event Swiftype's jQuery handlers will accept (keyCode can't be set via the constructor)
381                                        var send_key = function (type, code) {
382                                            var ev = new Event(type, {bubbles: true});
383                                            Object.defineProperty(ev, 'keyCode', {value: code});
384                                            Object.defineProperty(ev, 'which', {value: code});
385                                            box.dispatchEvent(ev);
386                                        };
387                                        // Swiftype sets autocomplete="off" on the box once it has bound its handlers.
388                                        // Then replay what the visitor did while st.js was still downloading.
389                                        var wait_until_ready = function (tries) {
390                                            if (box.getAttribute('autocomplete') === 'off') {
391                                                ready = true;
392                                                if (box.value !== '') {
393                                                    send_key('keyup', 0);
394                                                    if (enter_pending) {
395                                                        send_key('keydown', 13);
396                                                        send_key('keyup', 13);
397                                                    }
398                                                }
399                                            } else if (tries > 0) {
400                                                setTimeout(function () { wait_until_ready(tries - 1); }, 100);
401                                            }
402                                        };
403                                        var load_swiftype = function () {
404                                            if (loaded) return;
405                                            loaded = true;
406                                            var s = d.createElement('script');
407                                            s.async = true;
408                                            s.src = 'https://s.swiftypecdn.com/install/v2/st.js';
409                                            s.onload = function () { wait_until_ready(100); };
410                                            d.head.appendChild(s);
411                                        };
412                                        box.addEventListener('keydown', function (ev) {
413                                            if (!ready && (ev.key === 'Enter' || ev.keyCode === 13)) {
414                                                enter_pending = true;
415                                                ev.preventDefault();
416                                            }
417                                        });
418                                        // mouseenter / touchstart start the download a moment before focus
419                                        area.addEventListener('mouseenter', load_swiftype, {once: true});
420                                        area.addEventListener('touchstart', load_swiftype, {once: true, passive: true});
421                                        box.addEventListener('pointerdown', load_swiftype, {once: true});
422                                        box.addEventListener('focus', load_swiftype, {once: true});
423                                        // Enter sends visitors to search.php#stq=..., where Swiftype must load
424                                        // straight away to draw the results
425                                        if (w.location.pathname === '/search.php' || /[#&]stq=/.test(w.location.hash)) {
426                                            load_swiftype();
427                                        }
428                                    })(window, document, '_st');
429                                </script>
429
430                                <!-- End Swiftype search code -->
431                            </div>
432                                                    </div>
433                        <div id="headerRight">
434                            <nav>
435                                <div id="topNavRight">
436                                    <a id="contact" href="https://www.calculatorsoup.com/suggest-calculator.php" title="contact us or request new calculators or suggest changes">Contact</a>&nbsp;|&nbsp;<a href="https://www.calculatorsoup.com/calculators/" title="index of calculators">Calculator&nbsp;Index</a>
437                                </div>
438                            </nav>
439                        </div>
440                    </div>
441                </div>
442            </div>
443        </header>
444        <!-- end header file -->
445        <!-- open main content -->
446    <div id="contentMain" itemprop="mainContentOfPage">
447        <!-- open main -->
448        <main>
449                <!-- pop up basic calculator begin -->
450    <div data-swiftype-index="false" class="floatRight" id="basicCalculatorPop">
451
452        <a href="https://www.calculatorsoup.com/calculators/math/basic.php" target="_blank">Basic Calculator</a>
453
454        
455    </div><!-- pop up basic calculator end -->
456                <!-- breadcrumbs begin -->
457                
458        <div data-swiftype-index="false" id="breadcrumbs">
459        <div itemscope itemtype="https://schema.org/BreadcrumbList">
460        	<div itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
461                <a itemprop="item" href="https://www.calculatorsoup.com" title="Calculator Categories">
462                <span itemprop="name">Calculators</span>
463                <meta itemprop="position" content="1">
464	            </a>
465    	    </div>
466			 &gt; <div id="lastBreadcrumb"><div itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">		<a itemprop="item" href="https://www.calculatorsoup.com/suggest-calculator.php">
467										<span itemprop="name">Contact Us</span>
468										<meta itemprop="position" content="2">
469										</a>
470									</div></div>
471        </div>
472        </div>
473		                <!-- breadcrumbs end -->
474                        <h1 itemprop="name" id="pageH1">Contact Us</h1>
475            <!-- ad block 1 top and left begin -->
476            
477    
478            <!-- ad block 1 top and left end -->
479                        <!-- ad block 2 right begin -->
480                        <!-- ad block 2 right end -->
481            <!-- Content Block and Bottom Ads begin -->
482            <div id="contentBlock">
483                <div class="BlockMinWidth"></div>
484                                <!-- InstanceBeginEditable name="content" -->
485                                <p>Edward Furey
486                    <br />
487                   c/o <a href="https://www.calculatorsoup.com">CalculatorSoup, LLC</a>
488                    <br />
489                   508-231-1331
490                </p>
491                                    <p><a href="suggest-calculator.php?link=form">Contact Form</a></p>
492                                <p>&nbsp;</p>
493                <p>&nbsp;</p>
494                <p>&nbsp;</p>
495                <p>&nbsp;</p>
496                <p>&nbsp;</p>
497                <p>&nbsp;</p>
498                <p>&nbsp;</p>
499                <!-- InstanceEndEditable -->
500                <!-- ad block 3 bottom begin -->
501                
502    
503
504    <!-- Ads and Content 3 -->
505    
506
507    
508
509
510
511                <!-- ad block 3 bottom end -->
512            </div>
513            <!-- Content Block and Bottom Ads end -->
514                
515
516
517
518            <!-- small device follow buttons -->
519                    </main>
520        <!-- close main -->
521    </div>
522    <!-- close main content div -->
523</div>
524<!-- closed wrapper div -->
525<!-- start footer file -->
526<footer data-swiftype-index="false">
527    <div class="content">
528        <br>
529        <a href="https://www.calculatorsoup.com/help/">Help</a> |
530        <a href="https://www.calculatorsoup.com/suggest-calculator.php" title="request new calculators or suggest changes to a current online calculator">Requests &amp; Suggestions</a> |
531        <a href="https://www.calculatorsoup.com/contact.php">Contact Us</a>
532        <br>
533        <br>
534        <a href="https://www.calculatorsoup.com/legal.php">Legal Information &amp; Terms of Use</a> |
535        <a href="https://www.calculatorsoup.com/privacy.php">Privacy Policy</a>
536        <br>
537        <br>
538        <a href="https://www.calculatorsoup.com/" title="find a calculator online by category or search">Online Calculator Categories</a> |
539        <a href="https://www.calculatorsoup.com/calculators/" title="online calculators listed alphabetically">Calculator List</a> |
540        <a href="https://www.calculatorsoup.com/calculators/conversions/" title="Online Converters listed alphabetically">Converter List</a> |
541        <a href="https://www.calculatorsoup.com/sitemap.php" title="CalculatorSoup.com Sitemap">Site Map</a>
542        <div id="copyright">
543            <p>&copy; 2006 - 2026 CalculatorSoup&reg;<br>
544               All rights reserved.
545            </p>
546        </div>
547    </div>
548</footer>
549
550
551<!-- end footer file -->
552<!-- start footer script file -->
553
554
555
556
557
558<!-- end footer script file -->
559
560<!-- detect MathML -->
561
562
563
564<script>
565    // hide sticky ad when mobile keyboard opens
566    (function() {
567        // if (!window.visualViewport || window.innerWidth >= 768) return;
568        if (!window.visualViewport) return;
569
570        const adWrapper = document.getElementById('asc-ad-wrapper');
571        if (!adWrapper) return;
572
573        let initialHeight = window.visualViewport.height;
574
575        window.visualViewport.addEventListener('resize', function() {
576            // Update initial height on orientation change
577            if (window.visualViewport.height > initialHeight) {
578                initialHeight = window.visualViewport.height;
579            }
580
581            // Hide if viewport shrinks by more than 25%
582            if (window.visualViewport.height < initialHeight * 0.75) {
583                adWrapper.style.visibility = 'hidden';
584            } else {
585                adWrapper.style.visibility = '';
586            }
587        });
588    })();
589</script>
589
590
591<!-- InstanceBeginEditable name="foot" -->
592<!-- ad blocker detection bait: realistic ad size and common ad class names -->
593<div id="ad_unit" class="ad-placement textAd banner_ad pub_300x250 sponsored" style="width:300px;height:250px;position:absolute;left:-9999px;top:-9999px;"></div>
594<script>
595(function () {
596    var field = document.getElementById('ab');
597    if (!field) return;
598    field.value = 'js-ran';  //  tells apart "script ran" from "no javascript"
599
600    //  x means not measured yet
601    var signals = {bait: 'x', net: 'x', ctl: 'x'};
602
603    function report() {
604        field.value = 'bait:' + signals.bait + ';net:' + signals.net + ';ctl:' + signals.ctl;
605    }
606
607    //  cosmetic filtering: did the blocker hide or remove the bait div?
608    function check_bait() {
609        var bait = document.getElementById('ad_unit');
610        if (!bait) {
611            signals.bait = 1;  //  removed outright
612            return;
613        }
614        var bait_style = window.getComputedStyle(bait);
615        if (bait.offsetHeight === 0 || bait.offsetWidth === 0 ||
616            bait_style.display === 'none' || bait_style.visibility === 'hidden') {
617            signals.bait = 1;
618        } else {
619            signals.bait = 0;
620        }
621    }
622
623    //  network filtering: a request to a known ad host fails when blocked.
624    //  the same origin control request tells a blocker apart from a user
625    //  who is simply offline or behind a broken proxy.
626    function check_network() {
627        if (typeof fetch !== 'function') return;
628
629        fetch('https://securepubads.g.doubleclick.net/tag/js/gpt.js', {
630            method: 'HEAD',
631            mode: 'no-cors',
632            cache: 'no-store'
633        }).then(function () {
634            signals.net = 0;
635        }, function () {
636            signals.net = 1;
637        }).then(report);
638
639        fetch('/favicon.ico?ab=' + new Date().getTime(), {
640            method: 'HEAD',
641            cache: 'no-store'
642        }).then(function (response) {
643            signals.ctl = response.ok ? 'ok' : 'bad';
644        }, function () {
645            signals.ctl = 'bad';
646        }).then(report);
647    }
648
649    function run() {
650        check_bait();
651        report();
652    }
653
654    check_network();
655
656    //  measure late, filter lists and blocker extensions need time to settle
657    window.addEventListener('load', function () {
658        window.setTimeout(run, 2000);
659    });
660
661    //  measure again at submit, which is many seconds later still
662    var form = document.getElementById('CalculatorForm');
663    if (form) form.addEventListener('submit', run);
664})();
665</script>
665
666<!-- InstanceEndEditable -->
667</body>
668                                                <!-- InstanceEnd --></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.