PageSourceSearch

https://aaafx.com/

html aaafx.com collected 2026-10-04 13:24:10 UTC 21,229 bytes, 399 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5  <meta charset="UTF-8">
6  <!-- Provide `global` for node-style browser deps (e.g. react-zlib-js) without
7       rewriting it at build time (that corrupted core-js's ../internals/global-this). -->
8  <link rel="icon" href="/favicon.png">
9  
10
11  <!-- Warm up connections to third-party origins used early in page load so the
12       TLS/DNS handshake overlaps with HTML parsing instead of blocking later. -->
13  <!-- Keep this list short: Chrome warns past four preconnects, and each one
14       spends a connection slot that the critical requests could use. Only the
15       origins hit before first paint stay here (the geo lookup, jQuery and the
16       hero font); everything else is a cheap dns-prefetch below. -->
17  <link rel="preconnect" href="https://api.aaafx.com" crossorigin>
18
19  <link rel="preconnect" href="https://ajax.googleapis.com" crossorigin>
20  <!-- Web fonts (Unbounded/Inter) are served from fonts.gstatic.com; preconnect so
21       the font used by the hero heading (an LCP candidate) arrives sooner. -->
22
23  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
24  <!-- Preload the latin Unbounded face used by the headings above the fold. It is
25       declared with font-display: swap, so arriving late made the headings reflow
26       after first paint (~0.11 CLS on mobile, the tab-box shrinking from 147px to
27       119px). Discovering it here rather than after the stylesheet parses gets it
28       in before paint. Only this face is preloaded: adding Inter/Roboto too cost
29       ~200 ms of LCP competing for bandwidth without improving CLS further.
30       This URL must stay in sync with the @font-face rules in
31       public/assets/sass/font/_unbounded.scss; if it drifts the preload is merely
32       unused, never wrong. -->
33
34  <link rel="preload" as="font" type="font/woff2" crossorigin
35    href="https://fonts.gstatic.com/s/unbounded/v6/Yq6W-LOTXCb04q32xlpwu8Zf.woff2">
36  <!-- Preload the home hero image (the mobile LCP element). It lives in the lazy
37       home route chunk, so without this the browser only discovers it after the
38       JS boots and mounts. fetchpriority=high pulls it ahead of lower-priority
39       requests. Matches the <img> in src/views/home/index.vue. -->
40       
41  <link rel="preload" as="image" href="/assets/image/hero/bg-1.svg" fetchpriority="high">
42  <link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
43  <link rel="dns-prefetch" href="https://cdnjs.cloudflare.com">
44  <link rel="dns-prefetch" href="https://www.googletagmanager.com">
45  <link rel="dns-prefetch" href="https://cdn.livechatinc.com">
46  <link rel="dns-prefetch" href="https://metatraderweb.app">
47  <!-- jQuery and slick MUST stay in <head>, above the app's module script.
48       Vite injects 
48<script type="module" src="/assets/index-*.js"> at the end of
49       <head>, and `defer` scripts and module scripts execute in DOCUMENT order.
50       While these lived at the bottom of <body> they ran *after* the app booted,
51       so every component's mounted() hook that calls $(...) — header, footer,
52       home, mt4/mt5, crypto, account-types, act-trader, and every $().slick()
53       carousel init — threw "ReferenceError: $ is not defined".
54       `defer` still keeps them off the parser-blocking path. -->
55  
55<script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
55
56  
56<script defer type="text/javascript" src="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick.min.js"></script>
56
57  <!-- No maximum-scale: capping it at 1 blocks pinch-zoom, which fails the
58       accessibility audit and locks out anyone who needs to magnify the page. -->
59  <meta name="viewport" content="width=device-width, initial-scale=1">
60  <title>Trade Forex at zero commission - AAAFx</title>
61  <meta name="description"
62    content="Trade forex, commodities, stocks, indices, cyrptos with the most transparent broker with raw spreads from 0.0 pips and zero commission.">
63  <meta name="keywords"
64    content="Forex, AAAFx, forex broker, trade forex, trade cryptos, tight spreads,mt4, foreign exchange, open account, forex broker, forex trade, ">
65
66  <meta property="og:title" content="AAAFx">
67  <meta property="og:description" content="AAAFx">
68  <meta property="og:image" content="/global/assets/image/logo_black.svg">
69  <meta property="og:url" content="https://aaafx.com/">
70
71  <meta name="twitter:title" content="AAAFx">
72  <meta name="twitter:description" content="AAAFx">
73  <meta name="twitter:url" content="/assets/image/logo_black.svg">
74  <meta name="twitter:card" content="AAAFx">
75
76  <!-- Slick carousel CSS loaded non-render-blocking (carousels are below the
77       fold). The print->all media swap lets the browser paint first, then
78       apply these styles; <noscript> keeps it working without JS. -->
79  <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick.css"
80    media="print" onload="this.media='all'" />
81  <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick-theme.css"
82    media="print" onload="this.media='all'" />
83  <noscript>
84    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick.css" />
85    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick-theme.css" />
86  </noscript>
87  
87<script type="module" crossorigin src="/assets/index-010e327e.js"></script>
87
88  <link rel="modulepreload" crossorigin href="/assets/vue-vendor-bd567a24.js">
89  <link rel="modulepreload" crossorigin href="/assets/bootstrap-71154e5e.js">
90  <link rel="stylesheet" href="/assets/index-27fc820b.css">
91  <link rel="modulepreload" crossorigin href="/assets/index-1af62f8c.js">
92  <link rel="modulepreload" crossorigin href="/assets/discover-more-c1731183.js">
93  <link rel="modulepreload" crossorigin href="/assets/trading-account-types-1ee00cfb.js">
94  <link rel="modulepreload" crossorigin href="/assets/bg-1-27a91485.js">
95  <link rel="modulepreload" crossorigin href="/assets/fast_execution-3a3f49ab.js">
96  <link rel="modulepreload" crossorigin href="/assets/micro_Lots-bca66e08.js">
97  <link rel="modulepreload" crossorigin href="/assets/act-trader-c9f89d53.js">
98</head>
99
100<body>
101  <div id="app"></div>
102  <!-- Google Tag Manager (noscript) -->
vendor: 70 bytes, lines 102-103
102
103  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
103GTM-PN8CGG6
vendor: 91 bytes, lines 103-105
103" height="0" width="0"
104      style="display:none;visibility:hidden"></iframe></noscript>
105  
105<!-- End Google Tag Manager (noscript) -->
106
107  <!-- ===================================================================
108       Third-party tags: GTM, Google Ads, GA4, Teads, LiveChat, MetaTrader
109       widget and Criteo.
110
111       These all used to load during initial page load and were by far the
112       biggest drag on mobile. Measured against the same build, blocking them
113       took Total Blocking Time from ~1000 ms to 114 ms and LCP from 5.0 s to
114       2.6 s. TBT is what drives the INP failure in the field data, so instead
115       of loading up front, each tag now:
116
117         1. installs its queueing stub immediately (cheap, no network), so any
118            early gtag()/dataLayer.push()/LiveChatWidget call is still captured
119            and replayed once the real library arrives; and
120         2. fetches its script only once the page has loaded and the main thread
121            is idle, with a hard backstop so tags always fire on a quiet page.
122
123       Deferring means analytics pageviews land a few seconds later than before,
124       which can shift attribution slightly. That is deliberate.
125       =================================================================== -->
126  
126<script>
127    (function () {
128      // ---- queues installed now, so nothing early is dropped ----
129      window.dataLayer = window.dataLayer || [];
130      function gtag() { window.dataLayer.push(arguments); }
131      window.gtag = window.gtag || gtag;
132      gtag('js', new Date());
133      gtag('config', 'AW-10955579630');
134      gtag('config', 'G-M4SV51FR6C');
135
136      // LiveChat: build the queueing stub, but hold back init() -- that is the
137      // call that downloads tracking.js.
138      var lcInit;
139      window.__lc = window.__lc || {};
140      window.__lc.license = 19246054;
141      window.__lc.chat_between_groups = false;
142      (function (n, t, c) {
143        function i(n) { return e._h ? e._h.apply(null, n) : e._q.push(n) }
144        var e = {
145          _q: [], _h: null, _v: '2.0',
146          on: function () { i(['on', c.call(arguments)]) },
147          once: function () { i(['once', c.call(arguments)]) },
148          off: function () { i(['off', c.call(arguments)]) },
149          get: function () {
150            if (!e._h) throw new Error("[LiveChatWidget] You can't use getters before load.");
151            return i(['get', c.call(arguments)]);
152          },
153          call: function () { i(['call', c.call(arguments)]) },
154          init: function () {
155            var s = t.createElement('script');
156            s.async = !0; s.type = 'text/javascript';
157            s.src = 'https://cdn.livechatinc.com/tracking.js';
158            t.head.appendChild(s);
159          }
160        };
161        lcInit = e.init;
162        n.LiveChatWidget = n.LiveChatWidget || e;
163      }(window, document, [].slice));
164
165      window.criteo_q = window.criteo_q || [];
166
167      function load(src) {
168        var s = document.createElement('script');
169        s.async = true; s.src = src;
170        document.head.appendChild(s);
171      }
172
173      // The geo block below calls loadScripts() for Criteo, but it was never
174      // defined anywhere -- the call always threw (swallowed by its try/catch),
175      // so Criteo retargeting never actually loaded. This is that missing loader.
176      window.loadScripts = function (opts) {
177        var s = document.createElement('script');
178        s.src = opts.url;
179        var attr = (opts && opts.attr) || {};
180        for (var k in attr) {
181          if (Object.prototype.hasOwnProperty.call(attr, k)) s.setAttribute(k, attr[k]);
182        }
183        document.head.appendChild(s);
184      };
185
186      // Lets async code (e.g. the geo lookup) hand work to the deferred phase.
187      var queued = [], fired = false;
188      window.__deferTag = function (fn) { fired ? fn() : queued.push(fn); };
189
190      // Deliberately NOT triggered by user interaction. The GTM container alone
191      // costs ~785 ms of main-thread time on a mid-range phone, so firing it from
192      // a pointerdown/scroll handler would land all of that work on the user's
193      // first tap -- precisely the contention that makes INP fail. Idle time after
194      // load is early enough to be done before most first interactions, without
195      // ever competing with one.
196      function fire() {
197        if (fired) return;
198        fired = true;
199        window.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
200        load('https://www.googletagmanager.com/gtm.js?id=GTM-PN8CGG6');
201        // The GTM container already loads gtag.js for AW-10955579630 and
202        // G-M4SV51FR6C itself (a trace shows both fetched a second time with
203        // GTM's &cx=c&gtm=... parameters). Loading them here as well downloaded
204        // ~360 kB of duplicate script and executed it twice. The gtag() config
205        // calls queued above still apply — GTM's own gtag.js reads the same
206        // dataLayer. If a tag ever stops reporting, re-add the line for that ID.
207        load('https://p.teads.tv/teads-fellow.js');
208        // metatraderweb's widget.js only defines window.MetaTraderWebTerminal(),
209        // and nothing on the site ever calls it -- the platform pages link to the
210        // web terminal with a plain <a href> (static_vars.platformLinks.mt4/mt5.web)
211        // rather than embedding the iframe. So this bought nothing and cost a
212        // request that 404s in Chrome, putting a red error in every visitor's
213        // console. It 200s to curl, which is why it looks fine from a shell.
214        // The dns-prefetch below is deliberately kept: those <a href> links do
215        // go to metatraderweb.app, so resolving it early still helps the click.
216
217        // LiveChat mounts #chat-widget-container as its full 392x
217714 panel and
218        // only collapses it to the 84x84 launcher bubble ~2 s later. The
219        // container is position:fixed so it never moves *our* content, but
220        // Chrome still scores the widget's own 630 px jump as a layout shift --
221        // 0.22 CLS on the runs where that first panel is briefly visible. It is
222        // intermittent, so it does not move the p75 CrUX number, but it is a
223        // real shift and the largest one left on the page.
224        // visibility:hidden elements are excluded from layout-shift scoring, so
225        // holding the widget invisible until it has settled makes the collapse
226        // free. The launcher still appears long before anyone reaches for it.
227        // Note the reveal is driven entirely by timers set here and the
228        // stylesheet never hides the widget by itself, so no failure path can
229        // leave chat unreachable -- the worst case is a late bubble.
230        var lcHide = document.createElement('style');
231        lcHide.textContent = '#chat-widget-container{visibility:hidden!important}';
232        document.head.appendChild(lcHide);
233        var lcReveal = function () { if (lcHide.parentNode) lcHide.parentNode.removeChild(lcHide); };
234        // Reveal as soon as the container is launcher-sized, i.e. the panel has
235        // collapsed. A height of 0 means it is mounted but not laid out yet, so
236        // that does not count as settled.
237        var lcPoll = setInterval(function () {
238          var c = document.getElementById('chat-widget-container');
239          var h = c ? c.getBoundingClientRect().height : 0;
240          if (h > 40 && h < 200) { clearInterval(lcPoll); lcReveal(); }
241        }, 250);
242        setTimeout(function () { clearInterval(lcPoll); lcReveal(); }, 5000);
243        lcInit();
244        while (queued.length) {
245          try { queued.shift()(); } catch (e) { console.log(e); }
246        }
247      }
248
249      function schedule() {
250        if ('requestIdleCallback' in window) requestIdleCallback(fire, { timeout: 3000 });
251        else setTimeout(fire, 2000);
252      }
253      if (document.readyState === 'complete') schedule();
254      else window.addEventListener('load', schedule, { once: true });
255      setTimeout(fire, 8000); // backstop: never leave tags unfired
256    })();
257  </script>
257
258
259  <!--md5 tags-->
260
261  <noscript>
262    <a href="https://www.livechatinc.com/chat-with/19246054/" rel="nofollow">Chat with us</a>,
263    powered by <a href="https://www.livechatinc.com/?welcome" rel="noopener nofollow" target="_blank">LiveChat</a>
264  </noscript>
265  <noscript>
266    <a href="https://www.livechat.com/chat-with/13534029/" rel="nofollow">
267      Chat with us</a>, powered by <a href="https://www.livechat.com/?welcome" rel="noopener nofollow"
268      target="_blank">LiveChat</a>
269  </noscript>
270  
270<script type="text/javascript">
271    // let p_countries = {'AE':104591,'DE':104621,'DK':104622,'ES':104623,'ID':104624,'IT':103069,'KE':104625,'MA':104626,'MY':104627,'NG':104628,'NL':104629,'PH':104630,'PL':103068,'PT':104631,'SA':104632,'SE':104633,'SG':104634,'TH':104635,'ZA':104636};
272    let p_countries = { 'AE': 104591, 'DE': 104621, 'DK': 104622, 'ES': 104623, 'ID': 104624, 'IT': 103069, 'KE': 104625, 'MA': 104626, 'MY': 104627, 'NG': 104628, 'NL': 104629, 'PH': 104630, 'PL': 103068, 'PT': 104631, 'SA': 104632, 'SE': 104633, 'SG': 109525, 'TH': 109526, 'ZA': 104636, 'CA': 109527 };
273    const european_countries_list = {
274      "AT": '"Austria"',
275      "BE": '"Belgium"',
276      "BG": '"Bulgaria"',
277      "CY": '"Cyprus"',
278      "CZ": '"Czechia"',
279      "DE": '"Germany"',
280      "DK": '"Denmark"',
281      "EE": '"Estonia"',
282      "ES": '"Spain"',
283      "FI": '"Finland"',
284      "FR": '"France"',
285      "GR": '"Greece"',
286      "HR": '"Croatia"',
287      "HU": '"Hungary"',
288      "IE": '"Ireland"',
289      "IT": '"Italy"',
290      "LT": '"Lithuania"',
291      "LU": '"Luxembourg"',
292      "LV": '"Latvia"',
293      "MT": '"Malta"',
294      "NL": '"Netherlands"',
295      "PL": '"Poland"',
296      "PT": '"Portugal"',
297      "RO": '"Romania"',
298      "SE": '"Sweden"',
299      "SI": '"Slovenia"',
300      "SK": '"Slovakia"',
301      "CH": '"Switzerland"'
302    }
303    fetch('https://appapi.aaafx.com/get/geo').then(response => {
304      if (response.ok) {
305        return response.text();
306      } else {
307        throw new Error('HTTP Error ' + response.status);
308      }
309    }).then(country => {
310      if (country != '') {
311        try {
312          localStorage.setItem("ip_country", country);
313          let lang = ['AR', 'ES', 'TR', 'VI', 'PT', 'TH', 'ZH', 'ID']
314          if (lang.includes(country)) {
315            localStorage.setItem('lang', country.toLowerCase());
316          }
317          window.criteo_q = window.criteo_q || [];
318          if (p_countries[country]) {
319            // Handed to the deferred tag phase so Criteo does not compete with
320            // first paint. Runs immediately if that phase has already fired.
321            window.__deferTag(function () {
322              loadScripts({ 'url': ('//dynamic.criteo.com/js/ld/ld.js?a=' + p_countries[country]), 'attr': { 'async': "true" } }, p_countries[country]);
323            });
324          }
325        } catch (e) { console.log(e); }
326        let pathname = window.location.pathname;
327        if (!european_countries_list[country] && pathname.split("/").length > 1 && pathname.split("/")[1] != 'global') {
328          if (pathname == "/") {
329            pathname = '';
330          }
331          const { port, origin, search } = window.location;
332          let str = '/global' + pathname + search;
333          window.location = str;
334        }
335
336        if (window.location.search.includes("refLink")) {
337          var date = new Date();
338          date.setMonth(date.getMonth() + 12);
339          let link = window.location.search.split("=")[1]
340          document.cookie = "IBREFERLINK=" + link + ";expires=" + date + ";domain=.aaafx.com";
341
342          let decrpyLinRm = window.atob(link.toString());
343          let decrpyLinRm1 = decrpyLinRm.split('||')
344          //cons(decrpyLinRm,"---$$$$$-------",decrpyLinRm1)
345          document.cookie = "refLink=" + window.btoa(decrpyLinRm1[0]) + ";expires=" + date + ";domain=.aaafx.com";
346          document.cookie = "refRm=" + window.btoa(decrpyLinRm1[1]) + ";expires=" + date + ";domain=.aaafx.com";
347        }
348      }
349    }).catch(function (error) { console.log(error); });
350  </script>
350
351
352  <!-- jQuery and slick are loaded in <head> so they execute before this module;
353       see the comment there. -->
354  
355  <!-- The MetaTrader web widget is now loaded in the deferred tag phase above. -->
356  <!-- Font Awesome loaded non-render-blocking via the print->all media swap. -->
357  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
358    media="print" onload="this.media='all'" />
359  <noscript>
360    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
361  </noscript>
362  <!-- public/assets/js/myscript.js is NOT loaded: it starts with
363       `import $ from "jquery"`, which is a syntax error in a classic script, so
364       the browser threw on every page load and none of the file ever ran (its
365       slider setup is duplicated in the components' mounted() hooks anyway).
366       If it is ever needed again, drop the import and re-add the tag. -->
367  <!-- 
367<script src="https://prodstorage.azureedge.net/Widgets/lib/@1.0.0/widget-core.js"></script>
367
368  
368<script>
369    AcuityWidgets.globals({
370        apikey: '7dcdb63a-17e3-46b6-97b6-e296e141404d',
371        locale: 'en-GB'
372    });
373  </script>
373
374
375  
375<script>
376    !function(f,b,e,v,n,t,s)
377    {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
378    n.callMethod.apply(n,arguments):n.queue.push(arguments)};
379    if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
380    n.queue=[];t=b.createElement(e);t.async=!0;
381    t.src=v;s=b.getElementsByTagName(e)[0];
382    s.parentNode.insertBefore(t,s)}(window, document,'script',
383    'https://connect.facebook.net/en_US/fbevents.js');
384    fbq('init', '{682763263534928}');
385    fbq('track', 'PageView');
386  </script>
386
387  <noscript>
388    <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id={your-pixel-id-goes-here}&ev=PageView&noscript=1"/>
389  </noscript>
390  
390<script type="text/javascript">
391    (function(a,e,f,g,b,c,d){a[b]||(a.FintezaCoreObject=b,a[b]=a[b]||function(){(a[b].q=a[b].q||[]).push(arguments)},a[b].l=1*new Date,c=e.createElement(f),d=e.getElementsByTagName(f)[0],c.async=!0,c.defer=!0,c.src=g,d&&d.parentNode&&d.parentNode.insertBefore(c,d))})
392    (window,document,"script","https://aaafx.com/fz/core.js","fz");
393    fz("register","website",{id:"xsenvhfblhketmdxnnchygsavgwcsblzhl",trackHash:true,trackLinks:true,timeOnPage:true});
394  </script>
394 -->
395
396<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"ecd6eede56a8458eb2ba953c4301864a","r":1,"spa":2}' crossorigin="anonymous"></script>
396
397</body>
398
399</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.