🚛 找到完美的货运代理!

直接描述您正在寻找的货运公司,或请求报价——AI助您一臂之力!

10 014+
注册货运商
12 870+
企业客户
526+
积极评价的合作伙伴
4869 查看

ANGLIAI SZALLITAS

英国运输的条件如下:

  • 承运人须持有有效的运输许可证。
  • 承运人须持有有效的运输保险。
  • 如果运输ADR货物,须持有有效的ADR许可证。
  • 如果使用卡车运输,须配备有效的驾驶员监控记录仪(tachograph)。
  • 进行国际运输时,须持有有效的CMR保险。
  • 进行国际运输时,须持有有效的CMR单据。
  • 进行国际运输时,须持有有效的CMR发票。

此外,承运人还必须遵守英国运输相关的法规和规定。

关于英国运输的法规和规定包括:

  • 须遵守英国的交通法规。
  • 须遵守英国的工作场所安全规定。
  • 须遵守英国的环境保护法规。
  • 须遵守英国的海关法规。
  • 须遵守英国的ADR法规。
  • 须遵守英国的CMR法规。

英国运输的法规和规定可能会不断变化,因此运输公司必须保持最新信息。

如果您通过运输市场轻松、快捷且无义务地获取货运公司的报价。提交货运报价请求,可以节省时间和资金。您可以比较收到的报价,并在适当的情况下接受最佳报价。

货运报价请求 货物运输(托盘、箱子等) 货物和设备运输 汽车运输 搬家

Értékelné a választ? 0 0

Tovább a kérdések-válaszok oldalra

运输,覆盖整个欧洲
szente közúti szállítás
已加入超过13年 | (0)
Hungary magyarország veszprém
关于运输,欢迎随时联系我们!运输将根据协商使用3.5吨总重封闭式货车进行!
欧洲范围内优惠货运渡轮票销售 / 从英国返回货物
Freightlink - Kompokban Utazunk
已加入超过11年 | (0)
United Kingdom Quarry Bank, Chorley Road, Walton-le-Dale, Preston PR5 4JN
英国公司,成立超过10年,专注于欧洲范围内的优惠货运渡轮票销售和货运组织。
极速在线渡轮预订、跟踪、多语种客户服务、Freightlink 英国回程货运。
在整个欧洲运输,但主要是英国方向
Rostás Szilveszter
超过15年加入 | (0)
Hungary csór
罗斯塔什·西尔维谢特企业已加入货运市场平台European Freight Exchange超过12年。合作伙伴可靠性评级:无负面信息。具备货物运输、物流服务相关经验。联系方式:切尔,电话:0036203527512,电子邮箱:[email protected]。自我介绍如下:在整个欧洲进行运输,但以英国货运为主。该企业在货运市场上的链接:https://fuvarborze.hu/zh/fuvarozó/3960
NRG Freight Ltd. - 运输英国 - HU 与欧盟
NRG Freight Ltd.
已加入超过8年 | (0)
23 Isenburg Way, Hemel Hempstead, Egyesült Királyság
公司从事运输任务。我们的主要业务范围包括国际货运、空运、海运。我们总部位于英国,车队主要在英国和匈牙利之间运输商业货物,以及个人和企业的物流。与此同时,我们公司还在欧洲范围内提供整车及拼箱运输,价格具有竞争力。我们的座右铭是:任何任务都可以完成,无论面对多大的挑战。
中文翻译</div> <div id="company-30605-name" class="company-name">Tomee Trans & Trade</div> </div> <div style="text-align:right;"> <div class="company-card-meta">加入超过六年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <img src="/images/blank.png" class="flag flag-gb" /> <span style="font-weight:600;">Hungary Amethyst Close, London N11 2LW, Egyesült Királyság</span> </div> <div class="company-excerpt">自2011年以来,我们专注于英国包裹运输、海关清关、汽车、摩托车、机械设备运输以及宠物运输……</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=30605" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="17373" role="article" aria-labelledby="company-17373-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">Hun-Anc货运,英国总部的匈牙利货运公司。每周定期在英国和匈牙利之间提供运输服务。</div> <div id="company-17373-name" class="company-name">Hun-Ant Cargo</div> </div> <div style="text-align:right;"> <div class="company-card-meta">已加入超过11年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <img src="/images/blank.png" class="flag flag-gb" /> <span style="font-weight:600;">United Kingdom London N80AA 29. Effingham Road </span> </div> <div class="company-excerpt"></div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=17373" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="25492" role="article" aria-labelledby="company-25492-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">搬家、运输、家具和包裹在匈牙利和英格兰全境内的运输</div> <div id="company-25492-name" class="company-name">E.T.PELSO KFT</div> </div> <div style="text-align:right;"> <div class="company-card-meta">加入超过7年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 5 优秀"><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(5)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <span style="font-weight:600;">Hungary Balatonfenyves Nimród utca 1650/2 Hrsz</span> </div> <div class="company-excerpt">欧亚运输公司 \nhttp://www.csomagkuldes.co.uk/ \n\n包裹配送、仓储运输到匈牙利。12年经验。 \n目前我们拥有3辆梅赛德斯Sprinter轻型货车进行运输。 \n\n我们的服务: \n拥有12年经验的包裹派送及仓储运输公司! \n从事英国及国际仓储运输与货运业务。我们在欧洲多个国家成功开展了货运业务。 \n从一开始,准时可靠的工作和回头客一直是我们的核心价值。 \n熟知国内外市场,具备国际专业知识。</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=25492" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="28115" role="article" aria-labelledby="company-28115-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">货运、货物运输、搬家 价格实惠</div> <div id="company-28115-name" class="company-name">EU Trans LTD</div> </div> <div style="text-align:right;"> <div class="company-card-meta">加入超过7年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <img src="/images/blank.png" class="flag flag-gb" /> <span style="font-weight:600;">Hungary 77 High Street, Littlehampton, Egyesült Királyság</span> </div> <div class="company-excerpt">英国公司,提供欧洲范围内的包裹配送、托盘运输及货运代理服务,价格优惠。拥有所有必要的许可和全面的保险。</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=28115" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="41687" role="article" aria-labelledby="company-41687-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">欧洲货运运输</div> <div id="company-41687-name" class="company-name">sionspedition</div> </div> <div style="text-align:right;"> <div class="company-card-meta">已加入超过3年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <span style="font-weight:600;">Hungary Egrespatak 153 |RO- 457246 </span> </div> <div class="company-excerpt">Sion Spedition成立的目的是为了在运输领域为客户提供服务。我们的主要业务范围包括货运代理:公共车辆运输和货物配送。我们在罗马尼亚和英国设有办公室,为整个欧洲的客户提供服务。我们相信,只有以认真和高效的态度,才能确保与客户的良好合作。\n\n由专业人士组成的团队将为您提供汽车安全运输的保障。我们的公司在多个欧洲国家拥有可靠的合作伙伴,致力于为客户提供便利和保障。我们确保您的车辆在整个运输过程中安全,无论是途中还是停车环节,都由我们的公司及合作伙伴的任何一个地点负责。客户的车辆会按时取车并送达,按照运输订单上的指定地点。</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=41687" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="1909" role="article" aria-labelledby="company-1909-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">欧盟内经济型快递服务与搬家</div> <div id="company-1909-name" class="company-name">www.irfutar.com B-Trade Co.</div> </div> <div style="text-align:right;"> <div class="company-card-meta">加入超过17年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <img src="/images/blank.png" class="flag flag-ie" /> <span style="font-weight:600;">Ireland 9. Gardiner Place, Dublin1</span> </div> <div class="company-excerpt">快速、可靠且定期的快递和搬家服务,覆盖爱尔兰和匈牙利路线。\n包裹、箱子运输 - 狗、猫及宠物运输 - 家具、机械设备运输\n自行车和摩托车运输 - 汽车零配件订购与送货\n搬家 - 快递服务 - 国际运输 - 物流</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=1909" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="14285" role="article" aria-labelledby="company-14285-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">货物运输最长8米,最大2.7吨,全天候24小时</div> <div id="company-14285-name" class="company-name">Péteri László</div> </div> <div style="text-align:right;"> <div class="company-card-meta">已经加入超过12年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <img src="/images/blank.png" class="flag flag-hu" /> <span style="font-weight:600;">Hungary Hajdúszoboszló</span> </div> <div class="company-excerpt">特殊货物运输 8米长以内,2.7吨以下,全天候最快服务!\n\n我们可以运输任何适合8.5 x 2米平台,并且不超过2.7吨的货物。\n\n保证匿名,保密无忧!\n\n立即索取报价!>>>\n\n标签:\n汽车救援、汽车运输、货物运输、特殊救援、特殊运输、商用车救援、商用车运输、海外救援、海外运输、两车救援、两车运输、农业机械运输、长材运输</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=14285" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="17617" role="article" aria-labelledby="company-17617-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">运输、搬家、家具组装、家具设计、涂漆,价格实惠!</div> <div id="company-17617-name" class="company-name">Tomo Team Kft.</div> </div> <div style="text-align:right;"> <div class="company-card-meta">已加入超过10年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <img src="/images/blank.png" class="flag flag-hu" /> <span style="font-weight:600;">Hungary Pécs</span> </div> <div class="company-excerpt">国内运输\n- 货物运输 5公斤至1.5吨\n- 小包裹运输\n- 超尺寸、大件货物运输\n- 卡车出租、托盘运输\n- 国内快递、其他货物运输\n\n木工工程\n- 家具(卧室、办公)\n- 组装家具\n- 建筑木工\n- 木质覆盖\n- 木雕(装饰、图案、肖像)\n- 围栏、码头建造与维修\n- 前屋顶与半屋顶建造\n- 遮阳设备\n- 钣金工艺\n\n涂料\n- 室内外喷漆\n- 漆饰\n- 澆料</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=17617" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> <article class="search-list-item" data-id="13633" role="article" aria-labelledby="company-13633-name"> <div class="company-card-head"> <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px;"> <div style="flex:1; min-width:0;"> <div class="company-card-mini-title">在匈牙利全境的运输</div> <div id="company-13633-name" class="company-name">MBG-Sped Kft</div> </div> <div style="text-align:right;"> <div class="company-card-meta">已加入超过13年 | <span class="user-feedback-badge" title="合作伙伴可靠性评级: 没有负面信息"><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i><i class="bi bi-star-fill" style="color: #d3d3d3;"></i> <span style="margin-left:6px; color:#6c757d; font-size:12px;">(0)</span></span></div> </div> </div> </div> <div class="company-location" aria-hidden="false"> <img src="/images/blank.png" class="flag flag-hu" /> <span style="font-weight:600;">Hungary Tóalmás</span> </div> <div class="company-excerpt">尊敬的女士/先生!\r\n\r\n请允许我简要介绍我们的公司,并为您提供国内货物运输和国际货运方面的服务。\r\n\r\n我们公司是公路运输的专业机构。\r\n\r\n公路运输\r\n\r\n整车货运,传统或特殊运输\r\n出口和进口\r\n欧洲集拼运输\r\n我们的目标是实现增长,因此不断开发我们的计算机系统以及合作伙伴关系。\r\n\r\n我们的合作伙伴配备了最先进的车辆,车辆年龄不超过2-3年。其车辆符合最严格的国内和欧洲环保法规。\r\n\r\n每辆车辆都配备了卫星追踪器和手机,确保我们随时掌握货物的准确位置。\r\n\r\n我们公司的利益在于向新老客户提供准确信息,并满足最严格的要求。\r\n\r\n我们的工作特点:\r\n\r\n与客户的面对面联系\r\n\r\n货物追踪\r\n\r\n员工的责任感\r\n\r\n诚信与诚信\r\n\r\n安全性\r\n\r\n我们以具有竞争力的价格提供高质量的服务。\r\n\r\n希望以上内容令您满意,我们期待很快能将您纳入满意客户之列。\r\n\r\n此致:\r\n\r\nMenyhárt</div> <div class="company-actions"> <a class="button bg-white" href="https://fuvarborze.hu/zh/?link=company_box&id=13633" target="_blank"> <span class="mif-phone"></span> 联系信息 </a> </div> </article> </div> </div> <script type="text/javascript"> //document.getElementById('search-results').scrollIntoView(); </script> <div class='bubb'><h3>Nem találta meg amit keres? Próbálja meg az alábbi lehetőségeket is:</h3> <a href="https://fuvarborze.hu/zh/?link=list&keyword=Szállítás_Vál" class="hashTag"><span class="mif-search"></span> Szállítás Vál </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=Szállítás_Kék" class="hashTag"><span class="mif-search"></span> Szállítás Kék </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=Szállítás_Érd" class="hashTag"><span class="mif-search"></span> Szállítás Érd </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=Szállítás_Pap" class="hashTag"><span class="mif-search"></span> Szállítás Pap </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=ADR_szállítás" class="hashTag"><span class="mif-search"></span> ADR szállítás </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=ADR_1_szállítás" class="hashTag"><span class="mif-search"></span> ADR 1 szállítás </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=gép__szállitás" class="hashTag"><span class="mif-search"></span> gép szállitás </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=Gép_szállítás" class="hashTag"><span class="mif-search"></span> Gép szállítás </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=Szállítás_Nak" class="hashTag"><span class="mif-search"></span> Szállítás Nak </a> <a href="https://fuvarborze.hu/zh/?link=list&keyword=Szállítás_Vác" class="hashTag"><span class="mif-search"></span> Szállítás Vác </a> </div> <div class="search-list-trigger" id="search-list-trigger"></div> </div> <!-- új jobb oldali oldalsáv --> <aside class="calc-sidebar" aria-labelledby="sidebar-title"> <div class="sidebar-title" id="sidebar-title"> <i class="bi bi-award" style="color: #217af1; margin-right: 8px;"></i> 积极反馈 </div> <div class="sidebar-intro bubb"> <div class="intro-text"> 近20年的货运交易平台为您提供数千个可靠的货运合作伙伴。 </div> <div class="intro-links"> <a href="https://fuvarborze.hu/zh/?link=list&status=positive" class="sidebar-link"> <i class="bi bi-thumbs-up"></i> 推荐货运公司 </a> <a href="https://fuvarborze.hu/zh/?link=list&status=positive" class="sidebar-link"> <i class="bi bi-target"></i> 如何进入这里? </a> </div> </div> <div class="feedback-list"> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=1986" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Smitték Kft </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">加入超过17年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 为托运提供短期解决方案。请随时联系我们。 </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-06-23 16:50:53 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>Biofilt-air Kft</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=31898" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Qualtect Bt. </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">加入超过六年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 非常认真、注重细节、耐心、可靠。我只能对他/她说好话。感谢您的帮助和耐心。大胆推荐! </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-06-05 06:03:38 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>未知用户</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=23639" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Lovas Róbert Ciprián e.v. </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">已加入超过8年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 我们达成了合作协议,关于货运的完成一切顺利。 </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-06-04 08:06:02 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>Meridian-Logistics Kft</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=23639" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Lovas Róbert Ciprián e.v. </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">已加入超过8年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 正确的快速运输,提供照片作为货物提取的证明,事实上我从未提出过这样的要求。 这是我第一次使用这个网站,和Lovas Róbert Ciprián合作,非常满意。 推荐给大家! </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-06-04 06:59:06 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>未知用户</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=23639" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Lovas Róbert Ciprián e.v. </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">已加入超过8年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 非常好且诚实的商业伙伴,推荐给所有人。 </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-06-04 06:57:00 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>未知用户</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=11508" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Meridian-Logistics Kft </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">超过14年加入</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 可靠的委托方,从头到尾都可以信赖的货运。 </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-06-04 06:45:28 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>Lovas Róbert Ciprián e.v.</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=31898" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Qualtect Bt. </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">加入超过六年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 准确、可靠且非常灵活的客户服务。 </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-05-28 08:51:26 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>未知用户</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=41649" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> Tegmon Trans Srl </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">已加入超过3年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> prüm 送货回家的镰刀。非常乐于助人,价格也相当合理。 我敢大胆推荐给其他人。 我下一个货运也会交给他们 :) </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-05-11 14:13:56 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>未知用户</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=46144" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> LUNATRANS Hungary KFT </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">已加入超过两年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 我对它非常满意,强烈推荐。 </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-05-07 10:45:32 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>未知用户</strong> </div> </div> </a> </div> <div class="feedback-box bubb"> <a href="https://fuvarborze.hu/zh?link=company_box&id=46144" class="feedback-item-link" target="_blank"> <div class="feedback-header"> <div class="fb-company"> <i class="bi bi-building" style="color: #217af1; margin-right: 6px;"></i> LUNATRANS Hungary KFT </div> <div class="fb-rating"> <i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i><i class="bi bi-star-fill" style="color: #ffc107;"></i> <div class="fb-stats"> <i class="bi bi-award"></i> 5 </div> </div> <div class="fb-date-container"> <span class="fb-ago">已加入超过两年</span> </div> </div> <div class="feedback-content"> <div class="feedback-text"> <i class="bi bi-quote" style="color: #217af1; margin-right: 6px; font-size: 0.9rem;"></i> 我们达成了合作协议,关于货运的完成一切顺利。 </div> <span class="fb-date"> <i class="bi bi-calendar3" style="margin-right: 3px;"></i> 2026-04-23 08:09:45 </span> <div class="feedback-author text-end"> <i class="bi bi-person" style="margin-right: 4px;"></i> <strong>未知用户</strong> </div> </div> </a> </div> </div> <div class="sidebar-footer"> <a href="https://fuvarborze.hu/zh/?link=list" class="sidebar-cta"> <i class="bi bi-arrow-right-circle"></i> 更多货运合作伙伴 </a> </div> </aside> </div> <script> let page = 1; const limit = 12; const gallery = document.querySelector('.search-list'); let isLoading = false; const observer = new IntersectionObserver(entries => { if (entries[0].isIntersecting && !isLoading) { isLoading = true; page++; const params = new URLSearchParams(window.location.search); params.set('page', page); fetch(`?${params.toString()}`) .then(response => response.text()) .then(data => { const parser = new DOMParser(); const doc = parser.parseFromString(data, 'text/html'); const newItems = doc.querySelectorAll('.search-list-item'); newItems.forEach(item => { if (!isDuplicate(item)) { gallery.appendChild(item); } }); isLoading = false; }) .catch(() => { isLoading = false; }); } }, { threshold: 0.5 }); // Csak akkor aktiválódik, ha az elem 50%-ban látható // Figyeljük az oldal alján lévő elem megjelenését const loadMoreTrigger = document.getElementById("search-list-trigger"); observer.observe(loadMoreTrigger); function isDuplicate(newItem) { const existingItems = gallery.querySelectorAll('.search-list-item'); for (let item of existingItems) { if (item.innerHTML === newItem.innerHTML) { return true; } } return false; } </script> <style> .list-container { display: flex; } .list-middle { width: 800px; } @media (max-width: 768px) { .list-container { display: block; } .list-middle { margin: 0 5px; } } .search-list { display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; } .search-list-item { width: 100%; box-sizing: border-box; } .search-list-trigger { width: 100%; height: 50px; background: transparent; } </style> <style> /* Kompakt, modern kártya-stílus (sablon-specifikus) */ .search-list-item { background: #ffffff; border-radius: 12px; box-shadow: 0 6px 22px rgba(16, 24, 40, 0.06); padding: 14px; display: flex; flex-direction: column; gap: 10px; transition: transform .15s ease, box-shadow .15s ease; overflow: hidden; min-height: 160px; border: 1px dotted #8b9ec0ff; } .search-list-item:hover { transform: translateY(-6px); box-shadow: 0 14px 36px rgba(16, 24, 40, 0.10); } /* Fejléc: rövid reklámszöveg / cím és meta sor */ .company-card-head { display: flex; flex-direction: column; gap: 8px; } .company-card-head>div { display: flex; gap: 10px; align-items: flex-start; flex-direction: column; } .company-card-head>div>div:first-child { flex: 1; min-width: 0; } .company-card-meta { font-size: .85rem; color: #6b7280; margin-top: 4px; background: #f3f4f6; padding: 4px 8px; border-radius: 6px; } /* mini title */ .company-card-mini-title { font-size: .95rem; color: #0b3b66; font-weight: 700; margin: 0 0 4px 0; } /* Fő név — javítva: ne törjön karakterenként, normál sortörés */ .company-name { margin: 0; font-size: 1.1rem; color: #0b2540; font-weight: 700; line-height: 1.15; white-space: normal; /* engedi a sortörést */ overflow-wrap: anywhere; /* törje a hosszú szavakat szükség esetén */ word-break: normal; /* ne törjön karakterenként */ hyphens: auto; } /* Ország/székhely badge */ .company-location { display: inline-flex; gap: 8px; align-items: center; background: linear-gradient(90deg, #0f7bd7, #2979ff); color: #fff; padding: 6px 8px; border-radius: 6px; font-size: .9rem; } /* Leírás: vágás, de megjelenik a teljes tartalom a forrásban */ .company-excerpt { color: #374151; font-size: .95rem; line-height: 1.35; max-height: 6.4rem; /* ~4 sorra vág */ overflow: hidden; position: relative; } /* CTA gomb jobbra lent */ .company-actions { display: flex; gap: 8px; margin-top: auto; justify-content: flex-end; } .button.bg-white { background: #fff; border: 1px solid #e6e9ee; color: #0b3b66; padding: 8px 12px; border-radius: 8px; text-decoration: none; font-weight: 600; } .button.bg-white .mif-phone { margin-right: 6px; } /* Mobil reszponzív */ @media (max-width: 768) { .search-list-item { padding: 12px; min-height: auto; } .company-card-mini-title { font-size: .92rem; } .company-name { font-size: 1rem; } .company-excerpt { max-height: 5.2rem; } } </style> </div> </div> </div> </div> <style> .cookie-consent { position: fixed; bottom: 0; left: 0; width: 100%; background-color: rgba(255, 255, 255, 0.98); border-top: 1px solid #ddd; padding: 10px; text-align: center; z-index: 999999; border-radius: 10px 10px 0 0; box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05); } @media (max-width: 768px) { .cookie-consent { width: 100%; border-radius: 0; } } .cookie-consent span { color: #000; } .cookieButtons { margin-bottom: 30px; } .cookieButtons button { font-size: 20px; } .cookie-consent button { margin-left: 10px; } .miniclose { right: 10px; position: relative; top: -10px; } #calculatorModal { margin-top: 60px; } .calc-modal-close { margin-bottom: 50px; } </style> <!-- Cookie Consent --> <div class="cookie-consent" id="cookieConsent" style="display:none;"> <div> <a href='https://fuvarborze.hu/zh' target='_top' class='sitelogo'><img src='https://fuvarborze.hu/images/fuvarborze-logo.png' width='350' border='0'></a> <h3>欢迎您使用欧洲货运交易平台!</h3> </div> <div class="text-center cookieButtons"> <button class="btn btn-secondary btn-sm" id="declineCookies">❌ 拒绝</button> <button class="btn btn-primary btn-sm" id="acceptCookies">👍 接受</button> </div> <div style="font-size: 12px;"> 此网站使用 cookies,以提供最佳的运输市场用户体验。cookies 有助于个性化内容、分析访问者行为以及优化我们的服务。根据欧盟数据保护法规(GDPR),我们在此告知您,某些 cookies 仅在获得您的同意后使用。未获同意可能导致部分功能无法正常运作。欲了解更多信息,请阅读我们的《数据保护政策》: <a href='https://fuvarborze.hu/zh/?link=privacy'>数据保护声明</a>! </div> </div> <!-- Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-5NV6QBDV2H"></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'G-5NV6QBDV2H', { 'anonymize_ip': true }); </script> <script> // Cookie consent kezelése külön namespace-ben (function () { var cookieConsent = document.getElementById('cookieConsent'); var acceptCookies = document.getElementById('acceptCookies'); var declineCookies = document.getElementById('declineCookies'); // Check if cookies are already decided var consentVal = getCookie('cookies_accepted'); if (consentVal === 'true') { gtag('consent', 'update', { 'analytics_storage': 'granted' }); } else if (consentVal === 'false') { gtag('consent', 'update', { 'analytics_storage': 'denied' }); } else { // Not yet decided – show the bar cookieConsent.style.display = 'block'; } // Accept cookies - csak a cookie consent gombra if (acceptCookies) { acceptCookies.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); setCookie('cookies_accepted', 'true', 365); cookieConsent.style.display = 'none'; gtag('consent', 'update', { 'analytics_storage': 'granted' }); if (typeof window._barionGrantConsent === 'function') window._barionGrantConsent(); }); } // Decline cookies - csak a cookie consent gombra if (declineCookies) { declineCookies.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); setCookie('cookies_accepted', 'false', 365); cookieConsent.style.display = 'none'; gtag('consent', 'update', { 'analytics_storage': 'denied' }); }); } // Set cookie function setCookie(name, value, days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (value || "") + expires + "; path=/"; } // Get cookie function getCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } })(); </script> <div class="languageSelection" > <div id="languagesContainer"> <div class="languageItem currentLanguage">🇨🇳</div> <div class="languageItem hide"><a href="https://fuvarborze.hu/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇭🇺</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/en/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇬🇧</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/zh/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇨🇳</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/sk/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇸🇰</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/hr/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇭🇷</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/sl/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇸🇮</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/pl/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇵🇱</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/de/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇩🇪</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/fr/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇫🇷</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/it/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇮🇹</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/es/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇪🇸</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/pt/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇵🇹</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/nl/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇳🇱</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/el/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇬🇷</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/bg/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇧🇬</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/ro/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇷🇴</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/cs/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇨🇿</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/da/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇩🇰</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/et/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇪🇪</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/fi/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇫🇮</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/lt/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇱🇹</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/lv/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇱🇻</a></div><div class="languageItem hide"><a href="https://fuvarborze.hu/sv/fuvaroz%C3%B3-c%C3%A9gek/ANGLIAI_SZALLITAS">🇸🇪</a></div> </div> </div> <script> $(document).ready(function () { // Helper to decide if a URL points to login/registration (supports pretty URLs as well) function isLoginOrRegHref(href) { try { var a = document.createElement('a'); a.href = href; var hostOk = (!a.host || a.host === window.location.host); var q = a.search || ''; var p = (a.pathname || '').toLowerCase(); if (q.indexOf('link=login') !== -1 || q.indexOf('link=reg') !== -1) return true; // Match common pretty paths in multiple languages var re = /(regisztracio|regisztráció|bejelentkezes|belepes|signin|anmelden|login|register)\/?$/; if (re.test(p)) return true; // also allow language-prefixed like /en/signin/ var parts = p.split('/').filter(Boolean); if (parts.length >= 2) { var last = parts[parts.length-1]; if (re.test('/'+last)) return true; } return false; } catch(_) { return false; } } // Intercept clicks on login/register links to open chat login overlay $(document).on('click', 'a', function (e) { // Allow ctrl/cmd click to open new tab if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return; var href = $(this).attr('href') || ''; if (!isLoginOrRegHref(href)) return; e.preventDefault(); e.stopImmediatePropagation(); try { $('#loader').hide(); } catch(_) {} // Create chat login overlay if doesn't exist if ($('#chatLoginOverlay').length === 0) { $('body').append('<div id="chatLoginOverlay" style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;"><div id="chatLoginContainer" style="position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;"><span id="closeChatLogin" style="position:absolute;top:20px;right:30px;color:#fff;font-size:40px;font-weight:bold;cursor:pointer;z-index:10000;">×</span><div id="chatLoginContent"></div></div></div>'); // Close on X click $('#closeChatLogin').click(function() { $('#chatLoginOverlay').fadeOut(300); }); // Close on background click $('#chatLoginOverlay').click(function(e) { if (e.target.id === 'chatLoginOverlay' || e.target.id === 'chatLoginContainer') { $('#chatLoginOverlay').fadeOut(300); } }); } // Load the chat login form $.get('/modules/pages/chat_login.php?lang=zh', function (html) { $('#chatLoginContent').html(html); $('#chatLoginOverlay').fadeIn(300); }, 'html'); }); // Handle login form submit via AJAX inside modal $(document).on('submit', '#modalContent #loginForm', function (e) { e.preventDefault(); var $form = $(this); var data = $form.serialize(); var $btn = $form.find('input[type=submit], button[type=submit]').prop('disabled', true); $.post('/ajaxjobs/login.php', data, function (j) { if (j && j.ok) { // Success: close modal and refresh to reflect logged-in state $('#subscriptionNoticeModal').modal('hide'); // Emit a custom event in case pages want to hook in (chat continues without reload) $(document).trigger('user:loggedin', [j.user || null]); // On non-chat pages, reload to reflect login state if ($('#chatMessages').length === 0) { location.reload(); } } else { var msg = (j && j.error) ? j.error : '登录失败'; var $err = $('<div class="alert alert-danger" role="alert"></div>').text(msg); $form.prepend($err); } }, 'json').fail(function(){ var $err = $('<div class="alert alert-danger" role="alert"></div>').text('网络错误'); $form.prepend($err); }).always(function(){ $btn.prop('disabled', false); }); }); // Handle registration form submit via AJAX inside modal $(document).on('submit', '#modalContent #regForm', function (e) { e.preventDefault(); var $form = $(this); var data = $form.serialize(); var $submit = $form.find('button[type=submit], input[type=submit]'); $submit.prop('disabled', true); $.ajax({ url: '/modules/pages/reg.php', type: 'POST', data: data, dataType: 'html' }).done(function(resp){ // Replace modal content with the returned HTML (it already includes messages) $('#modalContent').html(resp); }).fail(function(){ var $err = $('<div class="alert alert-danger" role="alert"></div>').text('网络错误'); $form.prepend($err); }).always(function(){ $submit.prop('disabled', false); }); }); $('.currentLanguage').on('click', function (e) { $('.languageSelection .languageItem').toggle(); $('#languagesContainer').addClass('languagesContainer'); $(document).on('click', function (e) { if (!$(e.target).closest('.languageSelection').length) { $('#languagesContainer').removeClass('languagesContainer'); $('.languageSelection .languageItem').hide(); $('.currentLanguage').show(); } }); $(document).on('scroll', function (e) { if (!$(e.target).closest('.languageSelection').length) { $('#languagesContainer').removeClass('languagesContainer'); $('.languageSelection .languageItem').hide(); $('.currentLanguage').show(); } }); }); function lang_alert() { openModal('<div><p><span class="flag-with-badge"><img src="https://fuvarborze.hu//images/blank.png" class="flag flag-zh" alt="ZH" /><span class="country-badge">ZH</span></span>: 页面右下角可以切换语言</p><p><span class="flag-with-badge"><img src="https://fuvarborze.hu//images/blank.png" class="flag flag-" alt="" /><span class="country-badge"></span></span>: 页面右下角可以切换语言</p></div>'); $.cookie('dif_lang_alert', '1', { expires: 30, path: '/' }); $('.modal').on('hidden.bs.modal', function () { $('.currentLanguage').click(); $('#languagesContainer').addClass('blinking') setTimeout(function () { $('#languagesContainer').removeClass('blinking'); }, 2500); }); } if ($.cookie('dif_lang_alert') == undefined) lang_alert(); }); </script> <script> // Kupon visszaszámláló – minden .coupon-countdown elemre fut, élő és dinamikusan betöltött üzenetekre is function initCouponCountdowns() { document.querySelectorAll('.coupon-countdown:not([data-timer-init])').forEach(function(el) { el.setAttribute('data-timer-init', '1'); var expires = parseInt(el.getAttribute('data-expires'), 10); function tick() { var left = Math.max(0, expires - Date.now()); var m = Math.floor(left / 60000); var s = Math.floor((left % 60000) / 1000); el.textContent = m + ':' + (s < 10 ? '0' : '') + s; if (left > 0) setTimeout(tick, 1000); else el.closest('.coupon-success-card') && (el.closest('.coupon-success-card').style.opacity = '0.5'); } tick(); }); } // Futtatás DOM betöltéskor és minden AJAX után document.addEventListener('DOMContentLoaded', initCouponCountdowns); if (window.MutationObserver) { new MutationObserver(initCouponCountdowns).observe(document.body, {childList: true, subtree: true}); } </script> <!-- MODAL HTML SECTION --> <div class="modal fade" id="subscriptionNoticeModal" tabindex="-1" role="dialog" aria-labelledby="subscriptionNoticeModalLabel" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> <div class="modal-header bg-blue text-white"> <div class="modal-title" id="subscriptionNoticeModalLabel"><a href='https://fuvarborze.hu/zh' target='_top' class='sitelogo'><img src='https://fuvarborze.hu/images/fuvarborze-logo.png' width='350' border='0'></a></div> <button type="button" class="modal-close" data-dismiss="modal" aria-label="关闭"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body" id="modalContent"></div> <div class="modal-footer"> <button type="button" class="btn btn-secondary modal-close" data-dismiss="modal">关闭</button> </div> </div> </div> </div> <!-- CALCULATOR WIDGET (replacing the modal) --> <div id="calculatorWidget" class="calculator-widget"> <div class="calculator-header" id="calculatorHeader"> <div class="calculator-title"> <i class="bi bi-calculator"></i> 快速运费计算器 </div> <div class="calculator-controls"> <button type="button" class="calc-minimize-btn" id="calcMinimizeBtn"> <i class="bi bi-dash"></i> </button> </div> </div> <div class="calculator-body" id="calculatorBody"> <div class="text-center"> <div class="spinner-border" role="status"> <span class="visually-hidden">加载中...</span> </div> </div> </div> </div> <button id="scrollToTopBtn">🔝</button> <script> $(document).ready(function () { function isPwaInstalled() { const isStandaloneMedia = window.matchMedia('(display-mode: standalone)').matches || window.matchMedia('(display-mode: fullscreen)').matches || window.matchMedia('(display-mode: minimal-ui)').matches; // iOS Safari saját jelzője (Home Screen-ről indítva true) const isIOSStandalone = typeof window.navigator.standalone === 'boolean' ? window.navigator.standalone : false; // Ellenőrizzük, hogy a push engedélyezve van-e let isPushEnabled = false; if ('Notification' in window && Notification.permission === 'granted') { isPushEnabled = true; } //return isStandaloneMedia || isIOSStandalone || isPushEnabled; return isPushEnabled; } if (isPwaInstalled()) { // ne mutasd a „Tedd a kezdőképernyőre” bannert } else { // mutasd az iOS/Android telepítési útmutatót if ($.cookie('cookival_pwa_banner') !== '1' && false && true && false) { var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; var bannerText = isIOS ? "请在您的移动设备上安装“货运交易平台”应用程序,并开启通知,以便高效使用货运交易平台!" : "启用通知以高效使用货运交易平台!"; var bannerHtml = '<div id="cookivalPwaBanner" style="position:fixed;bottom:80px;left:10px;right:10px;z-index:99999;background:#fff;border:1px solid #007bff;border-radius:10px;padding:15px;text-align:center;box-shadow:0 2px 10px rgba(0,0,0,0.15);">' + '<img src="https://fuvarborze.hu/images/icon-192.png" align="left"><span style="font-size:16px;color:#007bff;">' + bannerText + '</span><br>' + '<a href="https://fuvarborze.hu/zh/?link=pushsub" class="btn btn-primary" style="margin-top:10px; color: #FFFFFF;">继续</a>' + '<button id="closeCookivalPwaBanner" style="position:absolute;top:-20px;right:-20px;background:none;border:none;font-size:30px;color:#007bff;cursor:pointer;">🅧</button>' + '</div>'; $('body').append(bannerHtml); $('#closeCookivalPwaBanner').on('click', function () { $('#cookivalPwaBanner').remove(); $.cookie('cookival_pwa_banner', '1', { expires: 10, path: '/' }); }); } } // Calculator widget kezelése var calculatorWidget = $('#calculatorWidget'); var calculatorHeader = $('#calculatorHeader'); var calculatorBody = $('#calculatorBody'); var calculatorFooter = $('.calculator-footer'); var calcMinimizeBtn = $('#calcMinimizeBtn'); var calcCloseBtn = $('#calcCloseBtn'); // Widget állapotának betöltése cookie-ból var isWidgetOpen = getCalcCookie('calc_widget_open') === 'true'; var isWidgetClosed = getCalcCookie('calc_widget_closed') === 'true'; // Ha nincs még cookie beállítva (első látogatás), akkor nyitva legyen if (getCalcCookie('calc_widget_open') === null && getCalcCookie('calc_widget_closed') === null) { isWidgetOpen = true; } // Kalkulátor tartalom betöltése function loadCalculatorContent() { if ($('#calculatorBody .spinner-border').length > 0) { $('#calculatorBody').html("<style>\n\/* === CALCULATOR PROFESSIONAL DESIGN === *\/\n\n.calc-page {\n display: flex;\n gap: 30px;\n max-width: 1200px;\n margin: 20px auto;\n padding: 0 15px;\n}\n\n.calc-container {\n flex: 1;\n background: linear-gradient(135deg, #ffffff 0%, #f8fbff 100%);\n border-radius: 16px;\n box-shadow: 0 8px 32px rgba(11, 111, 179, 0.12);\n padding: 32px;\n border: 1px solid rgba(11, 111, 179, 0.08);\n position: relative;\n overflow: hidden;\n}\n\n.calc-container::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, #217af1, #01a0c6, #217af1);\n border-radius: 16px 16px 0 0;\n}\n\n\/* === OVERRIDE GLOBAL STYLES === *\/\n.calc-container input,\n.calc-container textarea,\n.calc-container select {\n padding: 12px 16px !important;\n border: 2px solid #e1eaf4 !important;\n border-radius: 10px !important;\n background: #ffffff !important;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;\n font-size: 14px !important;\n color: #2c3e50 !important;\n transition: all 0.3s ease !important;\n width: 100% !important;\n box-sizing: border-box !important;\n}\n\n.calc-container input:focus,\n.calc-container textarea:focus,\n.calc-container select:focus {\n border-color: #217af1 !important;\n box-shadow: 0 0 0 3px rgba(33, 122, 241, 0.1) !important;\n outline: none !important;\n}\n\n.calc-container label {\n padding: 0 !important;\n margin: 0 0 8px 0 !important;\n background: transparent !important;\n border-radius: 0 !important;\n color: #2c3e50 !important;\n font-weight: 600 !important;\n font-size: 14px !important;\n display: block !important;\n}\n\n\/* Radio button and checkbox specific overrides *\/\n.calc-container input[type=\"radio\"],\n.calc-container input[type=\"checkbox\"] {\n width: auto !important;\n margin: 0 8px 0 0 !important;\n padding: 0 !important;\n display: inline-block !important;\n vertical-align: middle !important;\n}\n\n.calc-container .radio-group label,\n.calc-container .checkbox-group label {\n display: inline-block !important;\n margin: 0 15px 0 0 !important;\n font-weight: normal !important;\n cursor: pointer !important;\n vertical-align: middle !important;\n}\n\n\/* Header Design *\/\n.calc-header {\n text-align: center;\n margin-bottom: 40px;\n position: relative;\n}\n\n.calc-title {\n font-size: 2.2rem;\n font-weight: 700;\n color: #217af1;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 15px;\n}\n\n.calc-title i {\n background: linear-gradient(135deg, #217af1, #01a0c6);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n.calc-subtitle {\n color: #6c757d;\n font-size: 1.1rem;\n margin-top: 8px;\n font-weight: 400;\n}\n\n.free-badge {\n position: absolute;\n top: -8px;\n right: -10px;\n background: linear-gradient(135deg, #28a745, #20c997);\n color: white;\n font-size: 0.75rem;\n font-weight: 700;\n padding: 6px 14px;\n border-radius: 20px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: 0 4px 12px rgba(40, 167, 69, 0.25);\n border: 2px solid rgba(255, 255, 255, 0.3);\n}\n\n\/* Form Group Styling *\/\n.form-group {\n margin-bottom: 28px;\n position: relative;\n}\n\n.form-label {\n display: block;\n font-weight: 600;\n font-size: 1rem;\n color: #2c3e50;\n margin-bottom: 12px;\n padding: 8px 16px;\n background: linear-gradient(135deg, #217af1, #01a0c6);\n color: white;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(33, 122, 241, 0.2);\n position: relative;\n}\n\n.form-label::after {\n content: '';\n position: absolute;\n bottom: -4px;\n left: 16px;\n width: 0;\n height: 0;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-top: 4px solid #01a0c6;\n}\n\n\/* Input Styling *\/\n.form-control, .form-select {\n border: 2px solid #e9ecef;\n border-radius: 12px;\n padding: 14px 18px;\n font-size: 1rem;\n transition: all 0.3s ease;\n background: #ffffff;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);\n}\n\n.form-control:focus, .form-select:focus {\n border-color: #217af1;\n box-shadow: 0 0 0 3px rgba(33, 122, 241, 0.1);\n outline: none;\n transform: translateY(-1px);\n}\n\n.form-control::placeholder {\n color: #adb5bd;\n font-style: italic;\n}\n\n\/* Textarea Specific *\/\ntextarea.form-control {\n resize: vertical;\n min-height: 100px;\n}\n\n\/* Radio and Checkbox Groups *\/\n.options-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 12px;\n margin-top: 16px;\n}\n\n.option-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: #ffffff;\n border: 2px solid #e9ecef;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.3s ease;\n position: relative;\n}\n\n.option-item:hover {\n border-color: #217af1;\n background: #f8fbff;\n transform: translateY(-2px);\n box-shadow: 0 4px 12px rgba(33, 122, 241, 0.1);\n}\n\n\/* Radio and checkbox input styling within option-item *\/\n.option-item input[type=\"radio\"],\n.option-item input[type=\"checkbox\"] {\n width: 18px !important;\n height: 18px !important;\n margin: 0 !important;\n padding: 0 !important;\n cursor: pointer !important;\n position: relative !important;\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n border: 2px solid #e1eaf4 !important;\n background: #ffffff !important;\n border-radius: 4px !important;\n transition: all 0.3s ease !important;\n}\n\n.option-item input[type=\"radio\"] {\n border-radius: 50% !important;\n}\n\n.option-item input[type=\"radio\"]:checked,\n.option-item input[type=\"checkbox\"]:checked {\n background: #217af1 !important;\n border-color: #217af1 !important;\n}\n\n.option-item input[type=\"checkbox\"]:checked::before {\n content: '\u2713' !important;\n position: absolute !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%) !important;\n color: white !important;\n font-size: 12px !important;\n font-weight: bold !important;\n line-height: 1 !important;\n display: block !important;\n}\n\n.option-item input[type=\"radio\"]:checked::before {\n content: '' !important;\n position: absolute !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%) !important;\n width: 8px !important;\n height: 8px !important;\n background: white !important;\n border-radius: 50% !important;\n display: block !important;\n}\n\n.option-item label {\n margin: 0 !important;\n padding: 0 !important;\n background: transparent !important;\n color: #2c3e50 !important;\n font-weight: 500 !important;\n font-size: 14px !important;\n cursor: pointer !important;\n flex: 1 !important;\n line-height: 1.4 !important;\n border-radius: 0 !important;\n}\n\n.option-item input[type=\"radio\"]:checked + label,\n.option-item input[type=\"checkbox\"]:checked + label {\n color: #217af1;\n font-weight: 600;\n}\n\n.option-item input[type=\"radio\"]:checked,\n.option-item input[type=\"checkbox\"]:checked {\n accent-color: #217af1;\n}\n\n\/* Stand-alone checkboxes and radio buttons *\/\n.calc-container .form-check-input {\n width: 18px !important;\n height: 18px !important;\n margin: 0 8px 0 0 !important;\n padding: 0 !important;\n cursor: pointer !important;\n display: inline-block !important;\n vertical-align: middle !important;\n position: relative !important;\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n border: 2px solid #e1eaf4 !important;\n background: #ffffff !important;\n border-radius: 4px !important;\n transition: all 0.3s ease !important;\n}\n\n.calc-container .form-check-input[type=\"radio\"] {\n border-radius: 50% !important;\n}\n\n.calc-container .form-check-input:checked {\n background: #217af1 !important;\n border-color: #217af1 !important;\n}\n\n.calc-container .form-check-input[type=\"checkbox\"]:checked::before {\n content: '\u2713' !important;\n position: absolute !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%) !important;\n color: white !important;\n font-size: 12px !important;\n font-weight: bold !important;\n line-height: 1 !important;\n display: block !important;\n}\n\n.calc-container .form-check-input[type=\"radio\"]:checked::before {\n content: '' !important;\n position: absolute !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%) !important;\n width: 8px !important;\n height: 8px !important;\n background: white !important;\n border-radius: 50% !important;\n display: block !important;\n}\n\n.calc-container .form-check-label {\n margin: 0 !important;\n padding: 0 !important;\n background: transparent !important;\n color: #2c3e50 !important;\n font-weight: 500 !important;\n font-size: 14px !important;\n cursor: pointer !important;\n display: inline-block !important;\n vertical-align: middle !important;\n border-radius: 0 !important;\n line-height: 1.4 !important;\n}\n\n.calc-container .form-check-input:checked + .form-check-label {\n color: #217af1 !important;\n font-weight: 600 !important;\n}\n\n\/* Form Select elements *\/\n.calc-container .form-select,\n.calc-container select {\n padding: 12px 16px !important;\n border: 2px solid #e1eaf4 !important;\n border-radius: 10px !important;\n background: #ffffff !important;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;\n font-size: 14px !important;\n color: #2c3e50 !important;\n transition: all 0.3s ease !important;\n width: 100% !important;\n box-sizing: border-box !important;\n appearance: none !important;\n background-image: url(\"data:image\/svg+xml,%3csvg xmlns='http:\/\/www.w3.org\/2000\/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'\/%3e%3c\/svg%3e\") !important;\n background-position: right 12px center !important;\n background-repeat: no-repeat !important;\n background-size: 16px 12px !important;\n padding-right: 40px !important;\n}\n\n.calc-container .form-select:focus,\n.calc-container select:focus {\n border-color: #217af1 !important;\n box-shadow: 0 0 0 3px rgba(33, 122, 241, 0.1) !important;\n outline: none !important;\n}\n\n\/* Form Control elements *\/\n.calc-container .form-control {\n padding: 12px 16px !important;\n border: 2px solid #e1eaf4 !important;\n border-radius: 10px !important;\n background: #ffffff !important;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;\n font-size: 14px !important;\n color: #2c3e50 !important;\n transition: all 0.3s ease !important;\n width: 100% !important;\n box-sizing: border-box !important;\n}\n\n.calc-container .form-control:focus {\n border-color: #217af1 !important;\n box-shadow: 0 0 0 3px rgba(33, 122, 241, 0.1) !important;\n outline: none !important;\n}\n\n\/* Form Labels *\/\n.calc-container .form-label {\n padding: 0 !important;\n margin: 0 0 8px 0 !important;\n background: transparent !important;\n border-radius: 0 !important;\n color: #2c3e50 !important;\n font-weight: 600 !important;\n font-size: 14px !important;\n display: block !important;\n line-height: 1.4 !important;\n}\n\n\/* Button overrides *\/\n.calc-container button,\n.calc-container .btn {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;\n font-weight: 600 !important;\n border-radius: 10px !important;\n transition: all 0.3s ease !important;\n border: none !important;\n cursor: pointer !important;\n}\n\n.form-check-input {\n width: 20px;\n height: 20px;\n margin: 0;\n border: 2px solid #dee2e6;\n flex-shrink: 0;\n}\n\n.form-check-label {\n margin: 0;\n font-size: 0.95rem;\n color: #495057;\n cursor: pointer;\n line-height: 1.4;\n}\n\n\/* Special Requirements *\/\n.special-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 10px;\n margin-top: 16px;\n}\n\n\/* Submit Button *\/\n.submit-section {\n margin-top: 40px;\n text-align: center;\n}\n\n.btn-submit {\n background: linear-gradient(135deg, #217af1, #01a0c6);\n color: white;\n border: none;\n padding: 16px 48px;\n font-size: 1.1rem;\n font-weight: 600;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.3s ease;\n box-shadow: 0 4px 16px rgba(33, 122, 241, 0.3);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: relative;\n overflow: hidden;\n}\n\n.btn-submit::before {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);\n transition: left 0.5s;\n}\n\n.btn-submit:hover::before {\n left: 100%;\n}\n\n.btn-submit:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 24px rgba(33, 122, 241, 0.4);\n}\n\n.btn-submit:active {\n transform: translateY(0);\n}\n\n\/* Responsive Design *\/\n@media (max-width: 768px) {\n .calc-page {\n flex-direction: column;\n margin: 10px auto;\n padding: 0 10px;\n }\n \n .calc-container {\n padding: 24px 20px;\n }\n \n .calc-title {\n font-size: 1.8rem;\n }\n \n .options-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n \n .special-grid {\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n }\n \n .free-badge {\n position: static;\n display: inline-block;\n margin-top: 10px;\n }\n}\n\n\/* Success\/Error States *\/\n.form-group.success .form-control {\n border-color: #28a745;\n box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.1);\n}\n\n.form-group.error .form-control {\n border-color: #dc3545;\n box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.1);\n}\n\n\/* Loading State *\/\n.btn-submit.loading {\n pointer-events: none;\n opacity: 0.7;\n}\n\n.btn-submit.loading::after {\n content: '';\n position: absolute;\n width: 20px;\n height: 20px;\n margin: auto;\n border: 2px solid transparent;\n border-top-color: #ffffff;\n border-radius: 50%;\n animation: spin 1s ease infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n\/* Hidden Fields Animation *\/\n.form-group {\n opacity: 1;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.form-group.hidden {\n opacity: 0;\n max-height: 0;\n margin-bottom: 0;\n}\n<\/style>\n\n<div class=\"calc-page\">\n <div class=\"calc-container\">\n \n <form id=\"freightForm\">\n <div class=\"form-group\">\n <label class=\"form-label\">\u8fd0\u8f93\u7c7b\u578b<\/label>\n <div class=\"options-grid\">\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_raklapos\"\n value=\"\u6258\u76d8\u8d27\u7269\" required>\n <label class=\"form-check-label\" for=\"cargoType_raklapos\">\u6258\u76d8\u8d27\u7269<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_omleszett\"\n value=\"\u6563\u88c5\u8d27\u7269\">\n <label class=\"form-check-label\" for=\"cargoType_omleszett\">\u6279\u53d1\u8d27\u7269<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_gabona\"\n value=\"\u7cae\u98df\">\n <label class=\"form-check-label\" for=\"cargoType_gabona\">\u8c37\u7269<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_koltoztetes\"\n value=\"\u642c\u5bb6\">\n <label class=\"form-check-label\" for=\"cargoType_koltoztetes\">\u642c\u5bb6<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_jarmu\"\n value=\"\u8f66\u8f86\">\n <label class=\"form-check-label\" for=\"cargoType_jarmu\">\u8f66\u8f86\uff0c\u6c7d\u8f66\u8fd0\u8f93<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_munkagep\"\n value=\"\u65bd\u5de5\u673a\u68b0\">\n <label class=\"form-check-label\" for=\"cargoType_munkagep\">\u5de5\u4f5c\u673a\u68b0<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_gepberendezes\"\n value=\"\u8bbe\u5907\u88c5\u7f6e\">\n <label class=\"form-check-label\" for=\"cargoType_gepberendezes\">\u673a\u68b0\u8bbe\u5907<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_targyak\"\n value=\"\u7269\u54c1\u548c\u5de5\u5177\">\n <label class=\"form-check-label\" for=\"cargoType_targyak\">\u7269\u54c1 \/ \u5de5\u5177<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"radio\" name=\"cargoType\" id=\"cargoType_egyeb\"\n value=\"\u5176\u4ed6\">\n <label class=\"form-check-label\" for=\"cargoType_egyeb\">\u5176\u4ed6<\/label>\n <\/div>\n <\/div>\n <\/div>\n\n <div class=\"form-group\">\n <label for=\"from\" class=\"form-label\">\u6765\u81ea\u54ea\u91cc<\/label>\n <input type=\"text\" class=\"form-control\" id=\"from\" name=\"from\" \n placeholder=\"\u8bf7\u8f93\u5165\u53d1\u8d27\u5730\u70b9...\" required>\n <\/div>\n\n <div class=\"form-group\">\n <label for=\"to\" class=\"form-label\">\u53bb\u54ea\u513f<\/label>\n <input type=\"text\" class=\"form-control\" id=\"to\" name=\"to\" \n placeholder=\"\u8bf7\u8f93\u5165\u76ee\u7684\u5730...\" required>\n <\/div>\n\n <div class=\"form-group\" id=\"weightGroup\">\n <label for=\"weight\" class=\"form-label\">\u91cd\u91cf\uff08\u516c\u65a4\uff09<\/label>\n <input type=\"number\" class=\"form-control\" id=\"weight\" name=\"weight\" \n placeholder=\"\u8bf7\u8f93\u5165\u91cd\u91cf\uff08\u4ee5\u516c\u65a4\u8ba1\uff09\">\n <\/div>\n\n <div class=\"form-group\" id=\"quantityGroup\">\n <label for=\"quantity\" class=\"form-label\">\u6570\u91cf<\/label>\n <input type=\"number\" class=\"form-control\" id=\"quantity\" name=\"quantity\" \n placeholder=\"\u8bf7\u63d0\u4f9b\u6570\u91cf...\">\n <\/div>\n\n <div class=\"form-group\" id=\"unitGroup\">\n <label for=\"unit\" class=\"form-label\">\u6570\u91cf\u5355\u4f4d<\/label>\n <select class=\"form-select\" id=\"unit\" name=\"unit\">\n <option value=\"\">\u8bf7\u9009\u62e9\u5355\u4f4d...<\/option>\n <option value=\"\u6258\u76d8\">\u6258\u76d8<\/option>\n <option value=\"\u4ef6\u6570\">\u4ef6\u6570<\/option>\n <option value=\"\u7acb\u65b9\u7c73\">\u7acb\u65b9\u7c73<\/option>\n <option value=\"\u7bb1\u5b50\">\u7bb1\u5b50<\/option>\n <option value=\"\u62c9\u8fbe\u7c73\u7279\">\u6db2\u538b\u6cb9\u8868<\/option>\n <option value=\"\u5176\u4ed6\">\u5176\u4ed6<\/option>\n <\/select>\n <\/div>\n\n <div class=\"form-group\" id=\"dimensionGroup\">\n <label for=\"dimensions\" class=\"form-label\">\u5c3a\u5bf8\uff08\u957f x \u9ad8 x \u5bbd\uff0c\u5398\u7c73\uff09<\/label>\n <input type=\"text\" class=\"form-control\" id=\"dimensions\" name=\"dimensions\"\n placeholder=\"\u4f8b\u5982\uff1a120x80x150\">\n <div class=\"option-item\" style=\"margin-top: 12px;\">\n <input type=\"checkbox\" class=\"form-check-input\" id=\"dimensionCheckbox\" name=\"dimensionCheckbox\"\n value=\"\u6807\u51c6\u6b27\u6807\u6258\u76d8\u5c3a\u5bf8 (120x80x150 \u5398\u7c73)\">\n <label class=\"form-check-label\"\n for=\"dimensionCheckbox\">\u6807\u51c6\u6b27\u6807\u6258\u76d8\u5c3a\u5bf8 (120x80x150 \u5398\u7c73)<\/label>\n <\/div>\n <\/div>\n\n <div class=\"form-group\" id=\"vehicleGroup\">\n <label for=\"vehicle\" class=\"form-label\">\u8f66\u8f86\u9700\u6c42<\/label>\n <select class=\"form-select\" id=\"vehicle\" name=\"vehicle\">\n <option value=\"\">\u9009\u62e9\u8f66\u8f86<\/option>\n <option value=\"\u6211\u4e0d\u786e\u5b9a\u80fd\u5305\u542b\u4ec0\u4e48\">\u6211\u4e0d\u786e\u5b9a\u80fd\u5305\u542b\u4ec0\u4e48<\/option>\n <option value=\"3,5\u5428\u8d27\u8f66\uff081,2\u5428\u8f7d\u91cd\uff09\">3,5\u5428\u8d27\u8f66\uff081,2\u5428\u8f7d\u91cd\uff09<\/option>\n <option value=\"7.5\u5428\u5361\u8f66\uff083\u5428\u8f7d\u91cd\uff09\">7.5\u5428\u5361\u8f66\uff083\u5428\u8f7d\u91cd\uff09<\/option>\n <option value=\"12\u5428\u5361\u8f66\uff086\u5428\u6709\u6548\u8f7d\u8377\uff09\">12\u5428\u5361\u8f66\uff086\u5428\u6709\u6548\u8f7d\u8377\uff09<\/option>\n <option value=\"\u4e32\u8054\uff0815\u5428\u6709\u6548\u8f7d\u8377\uff09\">Tandem\uff0815\u5428\u627f\u91cd\uff09<\/option>\n <option value=\"24\u5428\u6302\u8f66\uff0824\u5428\u6700\u5927\u8f7d\u91cd\uff09\">24\u5428\u6302\u8f66\uff0824\u5428\u6700\u5927\u8f7d\u91cd\uff09<\/option>\n <\/select>\n <\/div>\n\n <div class=\"form-group\" id=\"specialGroup\">\n <label class=\"form-label\">\u7279\u6b8a\u9700\u6c42<\/label>\n <div class=\"special-grid\">\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"checkbox\" name=\"special\" value=\"ADR\" id=\"adr\">\n <label class=\"form-check-label\" for=\"adr\">ADR<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"checkbox\" name=\"special\" value=\"\u8c03\u6e29\u7684\" id=\"temperalt\">\n <label class=\"form-check-label\" for=\"temperalt\">\u8c03\u8282\u6e7f\u5ea6<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"checkbox\" name=\"special\" value=\"\u5347\u964d\u5c3e\u95e8\" id=\"emelohatfal\">\n <label class=\"form-check-label\" for=\"emelohatfal\">\u5c3e\u677f forklift<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"checkbox\" name=\"special\" value=\"\u8d77\u91cd\u8f66\u8f86\" id=\"darus\">\n <label class=\"form-check-label\" for=\"darus\">\u8d77\u91cd\u8f66\u8f86<\/label>\n <\/div>\n <div class=\"option-item\">\n <input class=\"form-check-input\" type=\"checkbox\" name=\"special\" value=\"\u624b\u5de5\u88c5\u5378\" id=\"kezi\">\n <label class=\"form-check-label\" for=\"kezi\">\u624b\u5de5\u88c5\u5378<\/label>\n <\/div>\n <\/div>\n <\/div>\n \n <div class=\"form-group\">\n <label for=\"moreinfo\" class=\"form-label\">\u66f4\u591a\u4fe1\u606f<\/label>\n <textarea class=\"form-control\" id=\"moreinfo\" name=\"moreinfo\" rows=\"3\"\n placeholder=\"\u5728\u8fd0\u8f93\u65b9\u9762\u63d0\u4f9b\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f...\"><\/textarea>\n <\/div>\n \n <div class=\"submit-section\">\n <button type=\"submit\" class=\"btn-submit\">\n <i class=\"bi bi-send\"><\/i>\n \u8fd0\u8d39\u8ba1\u7b97\u8bf7\u6c42 <\/button>\n <\/div>\n <\/form>\n <\/div>\n <\/div>\n<script>\n \/\/ Smooth field visibility animations\n function toggleFields() {\n const type = $('input[name=\"cargoType\"]:checked').val();\n \n \/\/ Hide all optional groups first\n $('.form-group').removeClass('hidden');\n \n if (type === '\u642c\u5bb6') {\n $('#weightGroup, #quantityGroup, #unitGroup, #specialGroup, #dimensionGroup').addClass('hidden');\n $('#vehicleGroup').removeClass('hidden');\n } else if (type === '\u8f66\u8f86' || type === '\u65bd\u5de5\u673a\u68b0') {\n $('#quantityGroup, #unitGroup, #specialGroup, #vehicleGroup').addClass('hidden');\n $('#weightGroup, #dimensionGroup').removeClass('hidden');\n } else if (type === '\u8bbe\u5907\u88c5\u7f6e') {\n $('#quantityGroup, #unitGroup, #specialGroup').addClass('hidden');\n $('#weightGroup, #dimensionGroup, #vehicleGroup').removeClass('hidden');\n } else if (type === '\u6563\u88c5\u8d27\u7269' || type === '\u7cae\u98df') {\n $('#vehicleGroup, #dimensionGroup, #quantityGroup, #unitGroup, #specialGroup').addClass('hidden');\n $('#weightGroup').removeClass('hidden');\n } else {\n \/\/ Default: show all\n $('.form-group').removeClass('hidden');\n }\n }\n\n \/\/ EUR raklap m\u00e9ret checkbox functionality\n $('#dimensionCheckbox').on('change', function () {\n if ($(this).is(':checked')) {\n $('#dimensions').prop('disabled', true).addClass('disabled');\n } else {\n $('#dimensions').prop('disabled', false).removeClass('disabled');\n }\n });\n\n \/\/ Initialize\n $(document).ready(function() {\n \/\/ Radio button change handlers\n $('input[name=\"cargoType\"]').on('change', toggleFields);\n \n \/\/ Initial state\n toggleFields();\n \n \/\/ EUR checkbox initial state\n if ($('#dimensionCheckbox').is(':checked')) {\n $('#dimensions').prop('disabled', true).addClass('disabled');\n }\n \n \/\/ Form validation styling\n $('input[required], select[required]').on('blur', function() {\n const $group = $(this).closest('.form-group');\n if ($(this).val()) {\n $group.addClass('success').removeClass('error');\n } else {\n $group.addClass('error').removeClass('success');\n }\n });\n });\n\n \/\/ Form submission with enhanced UX\n $('#freightForm').submit(function (e) {\n e.preventDefault();\n \n const $submitBtn = $('.btn-submit');\n $submitBtn.addClass('loading').prop('disabled', true);\n \n \/\/ Collect form data\n const formData = $(this).serializeArray();\n let params = [];\n\n function getLabelText(name) {\n const $label = $(`[name=\"${name}\"]`).closest('.form-group').find('.form-label');\n if ($label.length) {\n return $label.text().trim();\n }\n if (name === 'special') {\n return '\u7279\u6b8a\u9700\u6c42';\n }\n return name;\n }\n\n $.each(formData, function (i, field) {\n if (field.value) {\n if (field.name === 'special') {\n params.push(field.value);\n } else {\n params.push(`${getLabelText(field.name)}: ${field.value}`);\n }\n }\n });\n\n const prompt = `\u6211\u60f3\u4e3a\u4ee5\u4e0b\u8d27\u8fd0\u8bf7\u6c42\u5feb\u901f\u8fd0\u8d39\u8ba1\u7b97: ${params.join(', ')}`;\n const url = `https:\/\/fuvarborze.hu\/chat\/?prompt=${encodeURIComponent(prompt)}`;\n \n \/\/ Simulate processing time for better UX\n setTimeout(() => {\n window.open(url, '_self');\n }, 500);\n });\n<\/script>\n"); } } // Widget megjelenítése function showCalculatorWidget() { calculatorWidget.addClass('show'); if (isWidgetOpen) { calculatorWidget.addClass('expanded'); calcMinimizeBtn.html('<i class="bi bi-dash"></i>'); } else { calculatorWidget.removeClass('expanded'); calcMinimizeBtn.html('<i class="bi bi-plus"></i>'); } loadCalculatorContent(); } // Widget elrejtése function hideCalculatorWidget() { return false; // Ha a felhasználó bejelölte, hogy ne jelenjen meg újra calculatorWidget.removeClass('show expanded'); setCalcCookie('calc_widget_closed', 'true', 1); } // Widget kinyitása/bezárása function toggleCalculatorWidget() { var isExpanded = calculatorWidget.hasClass('expanded'); if (isExpanded) { calculatorWidget.removeClass('expanded'); calcMinimizeBtn.html('<i class="bi bi-plus"></i>'); setCalcCookie('calc_widget_open', 'false', 30); } else { calculatorWidget.addClass('expanded'); calcMinimizeBtn.html('<i class="bi bi-dash"></i>'); setCalcCookie('calc_widget_open', 'true', 30); loadCalculatorContent(); } } // Eseménykezelők calculatorHeader.on('click', function (e) { if (!$(e.target).closest('.calculator-controls').length) { toggleCalculatorWidget(); } }); calcMinimizeBtn.on('click', function (e) { e.stopPropagation(); toggleCalculatorWidget(); }); calcCloseBtn.on('click', function (e) { e.stopPropagation(); if ($('#dontShowCalcWidgetAgain').is(':checked')) { setCalcCookie('dont_show_calc_widget', 'true', 1); } hideCalculatorWidget(); }); // Automatikus megjelenítés // Cookie funkciók function setCalcCookie(name, value, days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (value || "") + expires + "; path=/"; } function getCalcCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } // Eredeti modal eseménykezelők (változatlan) $('.modal-close').on('click', function () { $('#subscriptionNoticeModal').modal('hide'); }); }); </script> <style> .calculator-widget { position: fixed; bottom: 0; right: 50px; width: 400px; max-width: calc(100vw - 40px); background: white; border: 1px solid #ddd; border-radius: 10px 10px 0 0; box-shadow: 0 -5px 15px rgba(0, 0, 0, 0.2); z-index: 9999; transform: translateY(100%); transition: transform 0.3s ease-in-out; display: none; } .calculator-widget.show { display: block; transform: translateY(calc(100% - 60px)); } .calculator-widget.expanded { transform: translateY(0); } .calculator-header { background: #007bff; color: white; padding: 15px 20px; border-radius: 10px 10px 0 0; cursor: pointer; display: flex; justify-content: space-between; align-items: center; user-select: none; height: 60px; box-sizing: border-box; } .calculator-title { font-weight: bold; font-size: 16px; } .calculator-controls { display: flex; gap: 5px; } .calc-minimize-btn, .calc-close-btn { background: rgba(255, 255, 255, 0.2); border: none; color: white; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background-color 0.2s; } .calc-minimize-btn:hover, .calc-close-btn:hover { background: rgba(255, 255, 255, 0.3); } .calculator-body { padding: 20px; max-height: 400px; overflow-y: auto; } .calculator-footer { padding: 15px 20px; border-top: 1px solid #eee; background: #f8f9fa; } @media (max-width: 768px) { .calculator-widget { right: 10px; left: 10px; width: auto; max-width: none; } .calculator-header { padding: 12px 15px; height: 50px; } .calculator-widget.show { transform: translateY(calc(100% - 50px)); } .calculator-widget.expanded { transform: translateY(0) !important; } .calculator-title { font-size: 14px; } .calc-minimize-btn, .calc-close-btn { width: 25px; height: 25px; } } /* Eredeti modal CSS-ek eltávolítása/módosítása */ #calculatorModal { display: none !important; } </style> <div class="push-notification"></div> <script> $(document).ready(function () { var messages = [ "您好!您在寻找货运司机吗?", "让我们现在快速计算一下运费吧!", "需要运送什么货物以及目的地在哪里?", "或者您是运输公司吗?" ]; // Show alert once per day to everyone var alertKey = 'chat_daily_alert_shown'; var today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD if ($.cookie(alertKey) !== today && 1==2) { var alertText = "<h3>安全指南!</h3>为了您自身的安全,切勿提前通过转账支付运费!在货运市场上,货运公司被禁止提前索取运费。要查看货运市场的安全指南,请点击 <a href="#">这里</a>!"; $('.new-message').text('!'); $('.new-message').show(); $('.push-notification').show(); $('.push-notification').append('<div class="push-notification-alert" style="background: #e53935; color: #fff;">' + alertText + '<span class="push-notification-alert-close">✘</span></div>'); $('.push-notification-alert').on('click', function () { window.location.href = 'https://fuvarborze.hu/zh/ai/kerdesek-es-valaszok/fuvarborze-biztonsagi-iranyelvek'; $.cookie(alertKey, today, { expires: 1, path: '/' }); }); $('.push-notification-alert-close').on('click', function () { $(this).parent().remove(); $.cookie(alertKey, today, { expires: 1, path: '/' }); }); } var index = 0; if ($.cookie('chat_welcome_message') > 0 && $.cookie('chat_welcome_push_off') < 1 && 1==2) { for (var i = 0; i < $.cookie('chat_welcome_message'); i++) { $('.new-message').text(i + 1); $('.new-message').show(); $('.push-notification').show(); var message = messages[i]; $('.push-notification').append('<div class="push-notification-alert">' + message + '<span class="push-notification-alert-close">✘</span></div>'); $('.push-notification-alert').on('click', function () { $.cookie('chat_welcome_push_off', 1, { expires: 360, path: '/' }); window.location.href = 'https://fuvarborze.hu/zh/chat/'; }); $('.push-notification-alert-close').on('click', function () { $.cookie('chat_welcome_push_off', 1, { expires: 360, path: '/' }); $(this).parent().remove(); }); } } setInterval(function () { // Ha hangcsevegés folyamatban van, ne ellenőrizzünk és ne jelenítsünk meg értesítéseket if (window.fgptVoiceGlobal && window.fgptVoiceGlobal.running) { return; } $.get('/modules/chat/chatajax.php?proc=newmess_check&conversation_id=', function (data) { if (data.new_messages > 0) { if ($('.new-message').text() < 1) { var lastmessage_nr = 0; } else { var lastmessage_nr = parseInt($('.new-message').text()); } $('.new-message').text(data.new_messages); $('.new-message').show(); let currentLink = 'list'; if (currentLink != 'chat' && $.cookie('lastmessage_id') < data.lastmessage_id) { $('.push-notification').show(); for (var i = 0; i < data.messages.length; i++) { var message = data.messages[i].message; var message_id = data.messages[i].id; if (message_id > $.cookie('lastmessage_id')) { $('.push-notification').append('<div class="push-notification-item">' + message + '<span class="push-notification-item-close">✘</span></div>'); } } $.cookie('lastmessage_id', data.lastmessage_id, { expires: 360, path: '/' }); $('.push-notification-item').on('click', function () { window.location.href = 'https://fuvarborze.hu/zh/chat/'; }); $('.push-notification-item-close').on('click', function () { $(this).parent().remove(); }); } } else if ($.cookie('chat_welcome_push_off') < 1 && 0 == 0 && 1==2) { if ($.cookie('chat_welcome_message') == undefined || $.cookie('chat_welcome_message') == null) { $.cookie('chat_welcome_message', 0, { expires: 360, path: '/' }); } if (index < messages.length && $.cookie('chat_welcome_message') < messages.length) { $('.new-message').show(); var message = messages[$.cookie('chat_welcome_message')]; index = parseInt($.cookie('chat_welcome_message')) + 1; $('.new-message').text(index); if (index > $.cookie('chat_welcome_message') && $.cookie('chat_welcome_message') < messages.length) { $('.push-notification').show(); $('.push-notification').append('<div class="push-notification-item">' + message + '<span class="push-notification-item-close">✘</span></div>'); $('.push-notification-item').on('click', function () { window.location.href = 'https://fuvarborze.hu/zh/chat/'; }); $('.push-notification-item-close').on('click', function () { $(this).parent().remove(); }); $.cookie('chat_welcome_message', index, { expires: 360, path: '/' }); } } } }, 'json'); }, Math.floor(Math.random() * (30000 - 10000 + 1)) + 10000); // Poll every 10-30 seconds (was 2-10s, reduced MySQL load by ~70%) }); </script> <script> document.addEventListener('scroll', function () { var footerContent = document.getElementById('footerContent'); if (footerContent) { if (window.scrollY > 100) { footerContent.style.transform = 'translateY(100%)'; footerContent.style.transition = 'transform 0.3s ease-in-out'; } else { footerContent.style.transform = 'translateY(0)'; } } }); // Scroll to top gomb var scrollToTopBtn = document.getElementById('scrollToTopBtn'); if (scrollToTopBtn) { window.addEventListener('scroll', function () { if (window.pageYOffset > 300) { scrollToTopBtn.style.display = 'block'; } else { scrollToTopBtn.style.display = 'none'; } }); scrollToTopBtn.addEventListener('click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); }); } </script> <style> #scrollToTopBtn { position: fixed; bottom: 20px; left: 20px; background-color: #007bff; color: white; border: none; border-radius: 50%; width: 50px; height: 50px; font-size: 20px; cursor: pointer; display: none; z-index: 1000; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; } #scrollToTopBtn:hover { background-color: #0056b3; transform: scale(1.1); } @media (max-width: 768px) { #scrollToTopBtn { bottom: 80px; left: 10px; width: 40px; height: 40px; font-size: 16px; } .new-message { top: 0; } } @media (min-width: 768px) { .new-message { top: 90px; } } .new-message { position: absolute; right: 5px; top: 5px; background-color: red; color: white; font-weight: bold; border-radius: 50%; width: 25px; height: 25px; font-size: 12px; display: none; max-width: 25px; max-height: 25px; line-height: 21px; text-align: center; box-sizing: border-box; border: solid 2px #FFF; } .push-notification-alert { background: rgb(205, 246, 250); color: rgb(60, 108, 116); padding: 10px 15px; margin-top: 10px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); font-size: 14px; cursor: pointer; } .push-notification-alert-close { float: right; font-size: 20px; color: #000; cursor: pointer; margin-left: 10px; } .push-notification { position: fixed; width: 300px; display: none; top: 100px; right: 20px; z-index: 10000; } .push-notification-item-close { float: right; font-size: 20px; color: #000; cursor: pointer; margin-left: 10px; } .push-notification-item { background: rgb(177, 213, 252); color: rgb(60, 108, 116); padding: 10px 15px; margin-top: 10px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); font-size: 14px; cursor: pointer; } .blinking { animation: blink 1s infinite; } @keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } </style> <style> @media screen and (max-width: 768px) { .languageSelection { position: fixed; bottom: 40px; left: 20px; background: #FFFFFF; padding: 0; border: none; border-radius: 50%; cursor: pointer; z-index: 9998; box-shadow: 0 2px 10px rgba(0,0,0,0.15); } .languageSelection .currentLanguage { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 24px; } .languageSelection #languagesContainer.languagesContainer { position: absolute; bottom: 50px; left: 0; background: #fff; border-radius: 12px; padding: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.2); } } @media screen and (min-width: 768px) { .languageSelection { position: fixed; bottom: 40px; left: 20px; background: #FFFFFF; padding: 0; border: none; border-radius: 50%; cursor: pointer; z-index: 9998; box-shadow: 0 2px 10px rgba(0,0,0,0.15); } .languageSelection .currentLanguage { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 28px; } .languageSelection #languagesContainer.languagesContainer { position: absolute; bottom: 55px; left: 0; background: #fff; border-radius: 12px; padding: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.2); } } .languagesContainer { grid-template-columns: repeat(4, 1fr); grid-gap: 8px; display: grid; } .languageItem { cursor: pointer; text-align: center; font-size: 24px; line-height: 1; } .languageItem a { text-decoration: none; display: block; padding: 4px; border-radius: 6px; transition: background 0.15s; } .languageItem a:hover { background: #f0f0f0; } .modal-title img { height: 50px; width: auto; } #scrollToTopBtn { position: fixed; bottom: -15px; left: 50%; transform: translateX(-50%); background-color: white; color: #007bff; border: 2px solid #007bff; border-radius: 50%; width: 50px; height: 50px; font-size: 20px; cursor: pointer; display: none; z-index: 1000; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; } #scrollToTopBtn:hover { background-color: #007bff; color: white; transform: translateX(-50%) scale(1.1); } @media (max-width: 768px) { #scrollToTopBtn { bottom: 40px; width: 40px; height: 40px; font-size: 16px; } } .footer-content { position: fixed; bottom: 0; left: 0; width: 100%; background-color: #f8f9fa; border-top: 1px solid #ddd; padding: 10px; text-align: left; z-index: 1000; } </style> <!-- FreightGPT intro video modal (50% black overlay) --> <style> .fgpt-video-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: none; align-items: center; justify-content: center; z-index: 200000; padding: 20px; box-sizing: border-box; } .fgpt-video-modal.show { display: flex; } .fgpt-video-inner { width: min(1100px, 95vw); max-width: 1100px; background: transparent; border-radius: 12px; position: relative; display:flex; align-items:center; justify-content:center; max-height: 90vh; box-sizing: border-box; } /* Ensure video never overflows viewport height */ .fgpt-video-inner video { max-width: 100%; width: auto; height: auto; max-height: calc(90vh - 40px); display: block; border-radius: 8px; background: #000; object-fit: contain; } /* Reposition close button to avoid iOS volume overlay & hardware button area */ .fgpt-video-close { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 8px); right: calc(env(safe-area-inset-right, 0px) + 8px); width: 44px; height: 44px; border-radius: 50%; background: rgba(0,0,0,0.65); color: #fff; border: none; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 22px; box-shadow: 0 6px 18px rgba(0,0,0,0.5); z-index: 200001; backdrop-filter: blur(2px); } .fgpt-video-close:active { transform: scale(0.92); } @supports (padding: env(safe-area-inset-top)) { .fgpt-video-close { top: calc(env(safe-area-inset-top) + 8px); right: calc(env(safe-area-inset-right) + 8px); } } /* Speaker hint overlay */ .fgpt-audio-hint { position: absolute; top: 50px; left: 50%; transform: translateX(-50%); display: none; align-items: center; gap: 8px; background: rgba(0,0,0,0.6); color: #fff; padding: 8px 12px; border-radius: 999px; cursor: pointer; z-index: 200001; user-select: none; box-shadow: 0 4px 12px rgba(0,0,0,0.3); } .fgpt-audio-hint .icon { width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; } .fgpt-audio-hint .text { font-size: 14px; line-height: 1; white-space: nowrap; } @media (max-width: 768px) { .fgpt-video-inner { width: 94vw; max-height: 86vh; } /* JAVÍTVA: a width: 100% helyett auto, hogy az object-fit helyesen működjön */ .fgpt-video-inner video { max-height: calc(86vh - 32px); width: auto; max-width: 100%; } .fgpt-audio-hint { top: 40px; padding: 10px 14px; } } </style> <div id="fgpt-video-modal" class="fgpt-video-modal" role="dialog" aria-modal="true" aria-label="FreightGPT bemutató videó"> <button id="fgpt-video-close" class="fgpt-video-close" aria-label="Bezár">×</button> <div class="fgpt-video-inner"> <video id="fgpt-video" playsinline webkit-playsinline muted autoplay controls preload="auto"> <source src="https://fuvarborze.hu/images/videos/freightgpt-video.mp4" type="video/mp4"> 您的浏览器不支持视频播放。 </video> <div id="fgpt-audio-hint" class="fgpt-audio-hint" role="button" tabindex="0" aria-label="开启扬声器"> <span class="icon" aria-hidden="true"> <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor" focusable="false" aria-hidden="true"> <path d="M3 10v4h4l5 5V5L7 10H3zm13.5 2c0-1.77-1.02-3.29-2.5-4.03v8.06c1.48-.74 2.5-2.26 2.5-4.03z"></path> <path d="M14 3.23v2.06c2.89 0.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-0.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"></path> </svg> </span> <span class="text">请加载...</span> </div> </div> </div> <script> (function(){ function setFgptCookie(name, value, days){ var expires = ''; if (days){ var d = new Date(); d.setTime(d.getTime() + (days*24*60*60*1000)); expires = '; expires=' + d.toUTCString(); } document.cookie = name + '=' + encodeURIComponent(value || '') + expires + '; path=/'; } function getFgptCookie(name){ var nameEQ = name + '='; var ca = document.cookie.split(';'); for (var i=0;i<ca.length;i++){ var c = ca[i].trim(); if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length)); } return null; } var cookieName = 'fgpt_video_closed'; // Global function to open video modal (called from DataImport) window.openFgptVideoModal = function() { var modal = document.getElementById('fgpt-video-modal'); var vid = document.getElementById('fgpt-video'); var hint = document.getElementById('fgpt-audio-hint'); if (!modal || !vid) return; modal.classList.add('show'); // Attempt to play try { var p = vid.play(); if (p && typeof p.then === 'function') { p.catch(function(){ /* ignore */ }); } } catch(_){ } // Android controls fix var isAndroid = /Android/i.test(navigator.userAgent); if (isAndroid) { function ensureControls() { if (!vid.hasAttribute('controls')) vid.setAttribute('controls',''); vid.style.pointerEvents = 'auto'; } vid.addEventListener('loadedmetadata', ensureControls, { once: true }); vid.addEventListener('play', ensureControls); vid.addEventListener('click', ensureControls); vid.addEventListener('touchstart', ensureControls, { once: true }); } // Unmute on first interaction function unmuteOnFirstInteraction(){ if (vid.muted) vid.muted = false; if (hint) hint.style.display = 'none'; vid.removeEventListener('click', unmuteOnFirstInteraction); vid.removeEventListener('touchstart', unmuteOnFirstInteraction); } vid.addEventListener('click', unmuteOnFirstInteraction); vid.addEventListener('touchstart', unmuteOnFirstInteraction); // Show hint if still muted setTimeout(function(){ if (vid.muted && hint) { hint.style.display = 'flex'; } }, 900); // Hint click activates sound if (hint) { var activateSound = function(e){ e.preventDefault(); e.stopPropagation(); try { if (vid.muted) { vid.muted = false; vid.play().catch(function(){}); } } catch(_){} hint.style.display = 'none'; }; hint.addEventListener('click', activateSound); hint.addEventListener('keydown', function(ev){ if (ev.key === 'Enter' || ev.key === ' ') { activateSound(ev); } }); } }; try { var closed = getFgptCookie(cookieName); // DON'T show modal automatically anymore - only via attachment button // if (closed !== '1') { ... } var modal = document.getElementById('fgpt-video-modal'); var vid = document.getElementById('fgpt-video'); var modal = document.getElementById('fgpt-video-modal'); var vid = document.getElementById('fgpt-video'); var hint = document.getElementById('fgpt-audio-hint'); if (!modal || !vid) return; // Close handler document.getElementById('fgpt-video-close').addEventListener('click', function(e){ try { vid.pause(); } catch(_){} modal.classList.remove('show'); setFgptCookie(cookieName, '1', 360); // 360 days }); // Close when clicking outside modal.addEventListener('click', function(ev){ if (ev.target === modal){ try{ vid.pause(); }catch(_){ } modal.classList.remove('show'); setFgptCookie(cookieName, '1', 360); // 360 days } }); } catch(_e){ /* ignore cookie errors */ } })(); </script> <!-- Unread chat messages badge updater --> <script> (function() { function updateUnreadBadge() { fetch('/ajaxjobs/get_unread_count.php') .then(function(r) { return r.json(); }) .then(function(data) { console.log('Unread count response:', data); if (data && data.success) { var count = parseInt(data.count, 10) || 0; console.log('Unread count:', count); // Update mobile navbar badge var mobileBadge = document.querySelector('.mobile-navbar .new-message'); console.log('Mobile badge element:', mobileBadge); if (mobileBadge) { if (count > 0) { mobileBadge.textContent = count > 99 ? '99+' : count; mobileBadge.style.display = 'block'; } else { mobileBadge.style.display = 'none'; } } // Update desktop navbar badge var desktopBadge = document.querySelector('.navbar-chat-badge'); console.log('Desktop badge element:', desktopBadge); if (desktopBadge) { if (count > 0) { desktopBadge.textContent = count > 99 ? '99+' : count; desktopBadge.style.display = 'inline-block'; console.log('Badge updated to:', count); } else { desktopBadge.style.display = 'none'; } } } }) .catch(function(err) { console.log('Unread fetch error:', err); }); } // Initial check updateUnreadBadge(); // Update every 30 seconds setInterval(updateUnreadBadge, 30000); })(); </script> <!-- FreightGPT Global Modal --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <div id="freightgpt-global-modal" class="freightgpt-modal-overlay" style="display: none;"> <div class="freightgpt-modal-container"> <div class="freightgpt-modal-topbar"> <div class="freightgpt-modal-topbar-left"> <span class="freightgpt-modal-topbar-title"></span> </div> <div class="freightgpt-modal-topbar-right"> <a href="https://fuvarborze.hu/zh/?link=chat" class="freightgpt-modal-btn" title="全屏打开"> <i class="fa-solid fa-up-right-and-down-left-from-center"></i> </a> <button type="button" class="freightgpt-modal-btn freightgpt-modal-close-btn" onclick="closeFreightGPTModal()" title="关闭"> <i class="fa-solid fa-xmark"></i> </button> </div> </div> <div class="freightgpt-modal-body"> <iframe id="freightgpt-modal-iframe" src="about:blank" frameborder="0"></iframe> </div> </div> </div> <style> /* FreightGPT Global Modal Styles */ .freightgpt-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.75); z-index: 999999; display: flex; align-items: center; justify-content: center; opacity: 0; visibility: hidden; transition: opacity 0.3s ease, visibility 0.3s ease; } .freightgpt-modal-overlay.show { opacity: 1; visibility: visible; } .freightgpt-modal-container { width: 95%; max-width: 1100px; height: 90vh; max-height: 800px; background: #fff; border-radius: 16px; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 25px 80px rgba(0, 0, 0, 0.5); transform: scale(0.95) translateY(20px); transition: transform 0.3s ease; } .freightgpt-modal-overlay.show .freightgpt-modal-container { transform: scale(1) translateY(0); } /* Kis topbar a bezárás és expand gombokkal */ .freightgpt-modal-topbar { background: #1e293b; color: white; padding: 8px 12px; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; min-height: 40px; } .freightgpt-modal-topbar-left { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; } .freightgpt-modal-topbar-title { font-size: 13px; font-weight: 500; opacity: 0.9; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 500px; } .freightgpt-modal-topbar-right { display: flex; align-items: center; gap: 6px; } .freightgpt-modal-btn { width: 28px; height: 28px; border-radius: 6px; border: none; background: rgba(255, 255, 255, 0.1); color: white; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 14px; text-decoration: none; transition: background 0.2s ease; } .freightgpt-modal-btn:hover { background: rgba(255, 255, 255, 0.2); } .freightgpt-modal-close-btn:hover { background: #ef4444; } .freightgpt-modal-body { flex: 1; overflow: hidden; background: #f8fafc; } .freightgpt-modal-body iframe { width: 100%; height: 100%; border: none; } /* Mobile responsiveness */ @media (max-width: 768px) { .freightgpt-modal-container { width: 100%; height: 100%; max-height: 100%; max-width: 100%; border-radius: 0; } .freightgpt-modal-topbar-title { max-width: 200px; } } </style> <script> (function() { // FreightGPT Modal State var freightGPTModal = { isOpen: false, iframeLoaded: false, currentPrompt: '', currentTitle: '' }; // Base URL for the chat var chatBaseUrl = 'https://fuvarborze.hu/zh/modules/pages/chatmodal.php'; /** * Open the FreightGPT Modal * @param {string} prompt - Optional prompt to send * @param {string} title - Optional title for the modal topbar */ window.openFreightGPTModal = function(prompt, title) { var modal = document.getElementById('freightgpt-global-modal'); var iframe = document.getElementById('freightgpt-modal-iframe'); var titleEl = modal.querySelector('.freightgpt-modal-topbar-title'); var expandLink = modal.querySelector('.freightgpt-modal-btn[href]'); if (!modal || !iframe) return; // Set title (opcionális - ha nincs title, üres marad) var displayTitle = title || ''; titleEl.textContent = displayTitle; freightGPTModal.currentTitle = displayTitle; freightGPTModal.currentPrompt = prompt || ''; // Build iframe URL var iframeUrl = chatBaseUrl; var params = []; if (prompt) { params.push('prompt=' + encodeURIComponent(prompt)); // Always force new conversation for prompts params.push('new=1'); } if (title) { params.push('title=' + encodeURIComponent(title)); } if (params.length > 0) { iframeUrl += '?' + params.join('&'); } // Update expand link var expandUrl = 'https://fuvarborze.hu/zh/?link=chat'; if (prompt) { expandUrl += '&prompt=' + encodeURIComponent(prompt) + '&new=1'; } if (title) { expandUrl += '&title=' + encodeURIComponent(title); } if (expandLink) { expandLink.href = expandUrl; } // Load iframe iframe.src = iframeUrl; // Show modal with animation modal.style.display = 'flex'; // Force reflow for animation modal.offsetHeight; modal.classList.add('show'); // Prevent body scroll document.body.style.overflow = 'hidden'; freightGPTModal.isOpen = true; }; /** * Close the FreightGPT Modal */ window.closeFreightGPTModal = function() { var modal = document.getElementById('freightgpt-global-modal'); var iframe = document.getElementById('freightgpt-modal-iframe'); if (!modal) return; // Hide with animation modal.classList.remove('show'); setTimeout(function() { modal.style.display = 'none'; // Clear iframe to stop any ongoing processes iframe.src = 'about:blank'; }, 300); // Restore body scroll document.body.style.overflow = ''; freightGPTModal.isOpen = false; // Clean URL parameters var urlParams = new URLSearchParams(window.location.search); if (urlParams.get('link') === 'chat') { urlParams.delete('link'); urlParams.delete('prompt'); urlParams.delete('title'); var newUrl = window.location.pathname; var remaining = urlParams.toString(); if (remaining) { newUrl += '?' + remaining; } window.history.replaceState({}, '', newUrl); } }; /** * Toggle modal */ window.toggleFreightGPTModal = function() { if (freightGPTModal.isOpen) { closeFreightGPTModal(); } else { openFreightGPTModal(); } }; // Close on ESC key document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && freightGPTModal.isOpen) { closeFreightGPTModal(); } }); // Close on overlay click (not on container) document.addEventListener('click', function(e) { if (e.target.id === 'freightgpt-global-modal') { closeFreightGPTModal(); } }); // Auto-open if URL parameters present })(); </script> <!-- Segíthetünk? badge --> <style> .help-badge { position: fixed; bottom: 40px; right: 20px; z-index: 9999; } .help-badge-btn { background: linear-gradient(135deg, #3b82f6, #1d4ed8); color: #fff; border: none; padding: 12px 20px; border-radius: 50px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 4px 15px rgba(59, 130, 246, 0.4); display: flex; align-items: center; gap: 8px; transition: transform 0.2s, box-shadow 0.2s; } .help-badge-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(59, 130, 246, 0.5); } .help-badge-btn .icon { font-size: 18px; } .help-popup { display: none; position: absolute; bottom: 60px; right: 0; width: 320px; background: #fff; border-radius: 16px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); overflow: hidden; animation: helpPopupIn 0.25s ease; } @keyframes helpPopupIn { from { opacity: 0; transform: translateY(10px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } .help-popup.show { display: block; } .help-popup-header { background: linear-gradient(135deg, #3b82f6, #1d4ed8); color: #fff; padding: 16px 20px; display: flex; justify-content: space-between; align-items: center; } .help-popup-header h3 { margin: 0; font-size: 16px; font-weight: 600; } .help-popup-close { background: rgba(255,255,255,0.2); border: none; color: #fff; width: 28px; height: 28px; border-radius: 50%; cursor: pointer; font-size: 16px; display: flex; align-items: center; justify-content: center; } .help-popup-close:hover { background: rgba(255,255,255,0.3); } .help-popup-body { padding: 20px; } .help-popup-body p { margin: 0 0 16px; font-size: 14px; color: #64748b; line-height: 1.5; } .help-popup-body input, .help-popup-body textarea { width: 100%; padding: 12px; border: 1px solid #e2e8f0; border-radius: 8px; font-size: 14px; margin-bottom: 12px; box-sizing: border-box; font-family: inherit; } .help-popup-body textarea { min-height: 100px; resize: vertical; } .help-popup-body input:focus, .help-popup-body textarea:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); } .help-popup-submit { width: 100%; background: linear-gradient(135deg, #3b82f6, #1d4ed8); color: #fff; border: none; padding: 12px; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; transition: opacity 0.2s; } .help-popup-submit:hover { opacity: 0.9; } .help-popup-submit:disabled { opacity: 0.7; cursor: not-allowed; } .help-loader { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: #fff; border-radius: 50%; animation: helpSpin 0.8s linear infinite; vertical-align: middle; margin-right: 6px; } @keyframes helpSpin { to { transform: rotate(360deg); } } @media (max-width: 728px) { .help-badge { right: 10px; bottom: 40px; } .help-popup { position: fixed; width: calc(100vw - 20px); right: 10px; left: 10px; bottom: auto; top: 50%; transform: translateY(-50%); max-height: calc(100vh - 100px); overflow-y: auto; } .help-popup-body textarea { min-height: 80px; } } </style> <div class="help-badge" id="helpBadge"> <div class="help-popup" id="helpPopup"> <div class="help-popup-header"> <h3>需要帮助吗?</h3> <button type="button" class="help-popup-close" onclick="toggleHelpPopup()">×</button> </div> <div class="help-popup-body"> <p>如有疑问或发现问题,请告诉我们,我们会尽快回复!</p> <textarea id="helpMessage" placeholder="请描述您的问题或遇到的错误..."></textarea> <div style="display:flex;gap:8px;align-items:stretch;"> <button type="button" class="help-popup-submit" id="helpSubmitBtn" onclick="submitHelpForm()" style="flex:1;">⌲ 消息发送</button> <style> /* Floating Voice Button - Global Styles */ .fgpt-global-voice-btn { transition: all 0.3s ease; user-select: none; -webkit-user-select: none; touch-action: none; height: auto; border: none; background: transparent; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; } .fgpt-global-voice-btn:active { cursor: grabbing; } .fgpt-voice-circle { width: 64px; height: 64px; border-radius: 50%; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #fff; box-shadow: 0 8px 24px rgba(16, 185, 129, 0.4); display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; } .fgpt-global-voice-btn:hover .fgpt-voice-circle { box-shadow: 0 12px 36px rgba(16, 185, 129, 0.5); transform: scale(1.08); } .fgpt-global-voice-btn.voice-active .fgpt-voice-circle { background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); box-shadow: 0 8px 24px rgba(239, 68, 68, 0.4); animation: voice-pulse 1.5s ease-in-out infinite; } .fgpt-global-voice-btn.voice-active .fgpt-voice-label { background: #fee2e2; color: #dc2626; } .fgpt-voice-circle svg { width: 30px; height: 30px; } /* Small indicator with bars and counter for active state */ .fgpt-voice-indicator-small { position: absolute; top: -20px; right: -20px; min-width: 50px; height: auto; border-radius: 12px; background: #fff; box-shadow: 0 2px 12px rgba(0,0,0,0.15); display: none; flex-direction: column; align-items: center; justify-content: center; padding: 6px 8px; gap: 4px; z-index: 2; } .fgpt-global-voice-btn.voice-active .fgpt-voice-indicator-small { display: flex; } /* Voice bars animation */ .fgpt-voice-bars { display: flex; align-items: center; justify-content: center; gap: 3px; height: 16px; } .fgpt-voice-bar { width: 3px; background: #ef4444; border-radius: 2px; animation: voice-bar-pulse 0.8s ease-in-out infinite; } .fgpt-voice-bar:nth-child(1) { height: 8px; animation-delay: 0s; } .fgpt-voice-bar:nth-child(2) { height: 12px; animation-delay: 0.1s; } .fgpt-voice-bar:nth-child(3) { height: 16px; animation-delay: 0.2s; } .fgpt-voice-bar:nth-child(4) { height: 12px; animation-delay: 0.3s; } .fgpt-voice-bar:nth-child(5) { height: 8px; animation-delay: 0.4s; } @keyframes voice-bar-pulse { 0%, 100% { transform: scaleY(0.5); opacity: 0.5; } 50% { transform: scaleY(1); opacity: 1; } } /* Timer counter */ .fgpt-voice-timer { font-size: 9px; font-weight: 600; color: #ef4444; font-family: monospace; line-height: 1; } @keyframes indicator-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } 50% { transform: scale(1.1); } } .fgpt-voice-label { position: relative; margin-top: -8px; padding: 6px 12px; background: #fff; color: #059669; font-size: 11px; font-weight: 700; text-align: center; line-height: 1.2; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); white-space: nowrap; z-index: 1; } @keyframes voice-pulse { 0%, 100% { box-shadow: 0 8px 24px rgba(239, 68, 68, 0.4); transform: scale(1); } 50% { box-shadow: 0 12px 36px rgba(239, 68, 68, 0.8); transform: scale(1.08); } } /* Voice Tooltip Bubble */ .fgpt-voice-tooltip { position: fixed; z-index: 99999; background: linear-gradient(135deg, #02beb5 0%, #01a79f 100%); color: #fff; padding: 16px 20px; border-radius: 16px; max-width: 280px; font-size: 14px; line-height: 1.5; box-shadow: 0 8px 24px rgba(2, 190, 181, 0.3), 0 2px 8px rgba(0, 0, 0, 0.1); opacity: 0; pointer-events: none; transition: opacity 0.3s ease, transform 0.3s ease; transform: translateY(10px); } .fgpt-voice-tooltip.show { opacity: 1; pointer-events: all; transform: translateY(0); } .fgpt-voice-tooltip::after { content: ''; position: absolute; bottom: -8px; left: 40px; width: 0; height: 0; border-left: 10px solid transparent; border-right: 10px solid transparent; border-top: 10px solid #01a79f; } .fgpt-tooltip-close { position: absolute; top: 8px; right: 8px; background: rgba(255, 255, 255, 0.2); border: none; color: #fff; width: 24px; height: 24px; border-radius: 50%; font-size: 18px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s ease; } .fgpt-tooltip-close:hover { background: rgba(255, 255, 255, 0.3); } @media screen and (max-width: 768px) { .fgpt-voice-tooltip { max-width: 240px; font-size: 13px; padding: 14px 18px; } .fgpt-voice-tooltip::after { left: 30px; } } /* Email input field for voice dictation */ .fgpt-voice-email-input { position: fixed; z-index: 99998; background: #fff; border-radius: 16px; padding: 20px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); display: none; flex-direction: column; gap: 12px; min-width: 320px; max-width: 400px; animation: emailInputSlideIn 0.3s ease-out; } .fgpt-voice-email-input.show { display: flex; } @keyframes emailInputSlideIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } .fgpt-voice-email-input h4 { margin: 0 0 8px 0; font-size: 16px; font-weight: 700; color: #1f2937; } .fgpt-voice-email-input p { margin: 0 0 12px 0; font-size: 13px; color: #6b7280; line-height: 1.4; } .fgpt-voice-email-input input[type="email"] { width: 100%; padding: 12px 14px; border: 2px solid #e5e7eb; border-radius: 8px; font-size: 15px; font-family: monospace; transition: border-color 0.2s ease; } .fgpt-voice-email-input input[type="email"]:focus { outline: none; border-color: #10b981; } .fgpt-voice-email-input .btn-group { display: flex; gap: 8px; } .fgpt-voice-email-input button { flex: 1; padding: 10px 16px; border: none; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; } .fgpt-voice-email-input .btn-confirm { background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #fff; } .fgpt-voice-email-input .btn-confirm:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3); } .fgpt-voice-email-input .btn-cancel { background: #f3f4f6; color: #6b7280; } .fgpt-voice-email-input .btn-cancel:hover { background: #e5e7eb; } /* Dynamic action buttons during voice call */ .fgpt-voice-action-buttons { position: fixed; z-index: 99997; display: none; flex-direction: column; gap: 8px; animation: slideInButtons 0.3s ease-out; } .fgpt-voice-action-buttons.show { display: flex; } @keyframes slideInButtons { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } .fgpt-action-btn { background: #fff; border: 2px solid #10b981; color: #059669; padding: 10px 16px; border-radius: 10px; font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2); white-space: nowrap; display: flex; align-items: center; gap: 6px; } .fgpt-action-btn:hover { background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #fff; transform: translateX(4px); box-shadow: 0 6px 16px rgba(16, 185, 129, 0.4); } .fgpt-action-btn svg { width: 16px; height: 16px; } /* Mobile responsive */ @media (max-width: 768px) { .fgpt-global-voice-btn { width: 64px; } .fgpt-voice-circle { width: 56px; height: 56px; } .fgpt-voice-circle svg { width: 26px; height: 26px; } .fgpt-voice-label { font-size: 10px; padding: 5px 10px; } .fgpt-welcome-content { margin: 20px; padding: 24px; } .fgpt-voice-email-input { min-width: 280px; max-width: calc(100vw - 40px); left: 20px !important; right: 20px !important; } } </style> <!-- Voice Tooltip Bubble (csak első látogatáskor) --> <div id="fgpt-voice-tooltip" class="fgpt-voice-tooltip"> <button class="fgpt-tooltip-close" id="fgpt-tooltip-close" aria-label="Bezárás">×</button> <div>您可以免费拨打货运交易所。您可以将“呼叫”按钮拖动到屏幕上最方便的位置。</div> </div> <!-- Floating Voice Button --> <button id="fgpt-global-voice-btn" class="fgpt-global-voice-btn" aria-label="调用FreightGPT" title="调用FreightGPT - 拖拽"> <div class="fgpt-voice-circle"> <svg width="30" height="30" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> <path d="M20.01 15.38c-1.23 0-2.42-.2-3.53-.56a.977.977 0 0 0-1.01.24l-1.57 1.97c-2.83-1.35-5.48-3.9-6.89-6.83l1.95-1.66c.27-.28.35-.67.24-1.02-.37-1.11-.56-2.3-.56-3.53 0-.54-.45-.99-.99-.99H4.19C3.65 3 3 3.24 3 3.99 3 13.28 10.73 21 20.01 21c.71 0 .99-.63.99-1.18v-3.45c0-.54-.45-.99-.99-.99z"/> </svg> <div class="fgpt-voice-indicator-small"> <div class="fgpt-voice-bars"> <div class="fgpt-voice-bar"></div> <div class="fgpt-voice-bar"></div> <div class="fgpt-voice-bar"></div> <div class="fgpt-voice-bar"></div> <div class="fgpt-voice-bar"></div> </div> <div class="fgpt-voice-timer">00:00</div> </div> </div> <span class="fgpt-voice-label" data-inactive-text="货运GPT调用" data-active-text="结束通话">货运GPT调用</span> </button> <!-- Email Input Panel (megjelenik amikor AI kéri az email címet) --> <div id="fgpt-voice-email-input" class="fgpt-voice-email-input"> <h4>电子邮箱确认</h4> <p>请核对并在必要时更正电子邮件地址:</p> <input type="email" id="fgpt-voice-email-field" placeholder="pelda@email.com" /> <div class="btn-group"> <button class="btn-confirm" id="fgpt-email-confirm">正确,可以开始</button> <button class="btn-cancel" id="fgpt-email-cancel">取消</button> </div> </div> <!-- Dynamic Action Buttons (megjelennek aktív hívás alatt) --> <div id="fgpt-voice-action-buttons" class="fgpt-voice-action-buttons"> <!-- Buttons will be dynamically inserted here --> </div> <script> (function() { 'use strict'; // Cookie helpers function fgptSetCookie(name, value, days) { const d = new Date(); d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000)); document.cookie = name + "=" + value + ";expires=" + d.toUTCString() + ";path=/"; } function fgptGetCookie(name) { const nameEQ = name + "="; const ca = document.cookie.split(';'); for (let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); } return null; } // Voice tooltip logic const voiceTooltip = document.getElementById('fgpt-voice-tooltip'); const tooltipClose = document.getElementById('fgpt-tooltip-close'); const voiceBtn = document.getElementById('fgpt-global-voice-btn'); const emailInput = document.getElementById('fgpt-voice-email-input'); const emailField = document.getElementById('fgpt-voice-email-field'); const emailConfirm = document.getElementById('fgpt-email-confirm'); const emailCancel = document.getElementById('fgpt-email-cancel'); const actionButtonsContainer = document.getElementById('fgpt-voice-action-buttons'); // Dynamic action buttons management var currentActionButtons = []; function showActionButtons(buttons) { // Clear existing buttons actionButtonsContainer.innerHTML = ''; currentActionButtons = []; if (!buttons || buttons.length === 0) { actionButtonsContainer.classList.remove('show'); return; } // Position buttons near voice button var btnRect = voiceBtn.getBoundingClientRect(); var left = btnRect.right + 20; var top = btnRect.top; // If too far right, position to the left if (left + 200 > window.innerWidth - 20) { left = btnRect.left - 220; } actionButtonsContainer.style.left = left + 'px'; actionButtonsContainer.style.top = top + 'px'; // Create buttons buttons.forEach(function(btn) { var button = document.createElement('button'); button.className = 'fgpt-action-btn'; button.innerHTML = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></svg>' + btn.label; button.onclick = function() { window.open(btn.url, '_blank'); }; actionButtonsContainer.appendChild(button); currentActionButtons.push(button); }); actionButtonsContainer.classList.add('show'); } function hideActionButtons() { actionButtonsContainer.classList.remove('show'); currentActionButtons = []; } // Position tooltip near voice button function positionTooltip() { var btnRect = voiceBtn.getBoundingClientRect(); var tooltipWidth = 280; // max-width from CSS var left = btnRect.left + (btnRect.width / 2) - (tooltipWidth / 2); var top = btnRect.top - 100; // Position above button // Ensure tooltip stays within viewport if (left < 20) left = 20; if (left + tooltipWidth > window.innerWidth - 20) { left = window.innerWidth - tooltipWidth - 20; } voiceTooltip.style.left = left + 'px'; voiceTooltip.style.top = top + 'px'; } // Check if user has seen tooltip const hasSeenTooltip = fgptGetCookie('fgpt_voice_welcome'); if (!hasSeenTooltip) { setTimeout(function() { positionTooltip(); voiceTooltip.classList.add('show'); }, 1500); } // Close tooltip function closeTooltip() { voiceTooltip.classList.remove('show'); fgptSetCookie('fgpt_voice_welcome', '1', 30); // 30 days } tooltipClose.addEventListener('click', closeTooltip); // Reposition tooltip on window resize window.addEventListener('resize', function() { if (voiceTooltip.classList.contains('show')) { positionTooltip(); } }); // Inactivity timer management (60 seconds - a max_response_output_tokens limitálja a válasz hosszát) var inactivityTimer = null; var INACTIVITY_TIMEOUT = 60000; // 60 seconds in milliseconds var aiSpeaking = false; // Track if AI is currently speaking window.resetInactivityTimer = function() { // Clear existing timer if (inactivityTimer) { clearTimeout(inactivityTimer); inactivityTimer = null; } // Only start timer if call is active AND AI is not speaking if (window.fgptVoiceGlobal && window.fgptVoiceGlobal.running && !aiSpeaking) { // console.log('[Voice] Inactivity timer reset (30s)'); inactivityTimer = setTimeout(function() { // console.log('[Voice] 30 seconds of inactivity detected, closing call...'); if (window.fgptVoiceGlobal && window.fgptVoiceGlobal.running) { window.fgptVoiceGlobal.stop(); } }, INACTIVITY_TIMEOUT); } }; // Pause inactivity timer when AI starts speaking window.pauseInactivityTimer = function() { aiSpeaking = true; if (inactivityTimer) { clearTimeout(inactivityTimer); inactivityTimer = null; } }; // Resume inactivity timer when AI stops speaking window.resumeInactivityTimer = function() { aiSpeaking = false; window.resetInactivityTimer(); }; // Clear inactivity timer when call ends window.addEventListener('fgpt-voice-stopped', function() { aiSpeaking = false; if (inactivityTimer) { clearTimeout(inactivityTimer); inactivityTimer = null; // console.log('[Voice] Inactivity timer cleared (call ended)'); } }); // Start inactivity timer when call begins window.addEventListener('fgpt-voice-started', function() { aiSpeaking = false; // console.log('[Voice] Call started, initializing inactivity timer'); window.resetInactivityTimer(); }); // Email input positioning near voice button function positionEmailInput() { var btnRect = voiceBtn.getBoundingClientRect(); var inputWidth = 320; var inputHeight = 200; // approximate // Try to position to the left of button var left = btnRect.left - inputWidth - 20; var top = btnRect.top; // If too far left, position to the right if (left < 20) { left = btnRect.right + 20; } // If too far right, center it if (left + inputWidth > window.innerWidth - 20) { left = (window.innerWidth - inputWidth) / 2; } // Keep vertical position in bounds if (top + inputHeight > window.innerHeight - 20) { top = window.innerHeight - inputHeight - 20; } if (top < 20) { top = 20; } emailInput.style.left = left + 'px'; emailInput.style.top = top + 'px'; } // Email input handlers var emailConfirmCallback = null; function showEmailInput(detectedEmail) { emailField.value = detectedEmail || ''; positionEmailInput(); emailInput.classList.add('show'); emailField.focus(); emailField.select(); } function hideEmailInput() { emailInput.classList.remove('show'); emailField.value = ''; emailConfirmCallback = null; } emailConfirm.addEventListener('click', function() { var email = emailField.value.trim(); if (email && emailConfirmCallback) { emailConfirmCallback(email); } hideEmailInput(); }); emailCancel.addEventListener('click', function() { hideEmailInput(); // Send cancellation message to AI if (window.fgptVoiceGlobal && window.fgptVoiceGlobal.dataChannel && window.fgptVoiceGlobal.dataChannel.readyState === 'open') { var cancelMsg = { type: 'conversation.item.create', item: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'Mégsem adom meg az email címemet most.' }] } }; window.fgptVoiceGlobal.dataChannel.send(JSON.stringify(cancelMsg)); window.fgptVoiceGlobal.dataChannel.send(JSON.stringify({ type: 'response.create' })); } }); emailField.addEventListener('keypress', function(e) { if (e.key === 'Enter') { emailConfirm.click(); } }); // --- Audio Context Management for Mobile --- // Create a single, reusable AudioContext for the entire page. // Mobile browsers require the AudioContext to be resumed by a user gesture. window.fgptAudioContext = new (window.AudioContext || window.webkitAudioContext)(); function ensureAudioContext() { return new Promise(function(resolve) { if (window.fgptAudioContext.state === 'suspended') { // console.log('AudioContext is suspended, attempting to resume...'); window.fgptAudioContext.resume().then(function() { // console.log('AudioContext resumed successfully.'); resolve(); }).catch(function(e) { // console.error('Failed to resume AudioContext:', e); // Even if it fails, resolve to not block the flow. // The browser might show its own permission prompt. resolve(); }); } else { // console.log('AudioContext is already running.'); resolve(); } }); } // Position management function getDefaultPosition() { const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const buttonHeight = voiceBtn.offsetHeight || 70; // Use actual height or fallback // Default: bottom-left (50px from left, 50px from bottom) const left = 50; let top = viewportHeight - buttonHeight - 50; // Ensure it stays within the viewport's bounds if (top < 20) { top = 20; // Minimum top margin } const maxLeft = Math.max(20, viewportWidth - (voiceBtn.offsetWidth || 70) - 20); const safeLeft = Math.min(Math.max(left, 20), maxLeft); return { left: safeLeft, top: top }; } function getSavedPosition() { const saved = fgptGetCookie('fgpt_voice_position'); if (saved) { try { return JSON.parse(saved); } catch(e) { return null; } } return null; } function savePosition(left, top) { const pos = JSON.stringify({ left: left, top: top }); fgptSetCookie('fgpt_voice_position', pos, 365); } function setPosition(pos) { voiceBtn.style.left = pos.left + 'px'; voiceBtn.style.top = pos.top + 'px'; } // Initialize position const savedPos = getSavedPosition(); if (savedPos) { setPosition(savedPos); } else { setPosition(getDefaultPosition()); } // Draggable functionality with click detection let isDragging = false; let hasMoved = false; let startX = 0, startY = 0; let initialX = 0, initialY = 0; let dragThreshold = 5; // pixel threshold to distinguish drag from click function handleStart(clientX, clientY) { isDragging = true; hasMoved = false; startX = clientX; startY = clientY; const rect = voiceBtn.getBoundingClientRect(); initialX = rect.left; initialY = rect.top; voiceBtn.style.transition = 'none'; } function handleMove(clientX, clientY) { if (!isDragging) return; const dx = clientX - startX; const dy = clientY - startY; // Check if moved beyond threshold if (!hasMoved && (Math.abs(dx) > dragThreshold || Math.abs(dy) > dragThreshold)) { hasMoved = true; } const newLeft = initialX + dx; const newTop = initialY + dy; // Keep within viewport const maxLeft = window.innerWidth - voiceBtn.offsetWidth; const maxTop = window.innerHeight - voiceBtn.offsetHeight; voiceBtn.style.left = Math.max(0, Math.min(newLeft, maxLeft)) + 'px'; voiceBtn.style.top = Math.max(0, Math.min(newTop, maxTop)) + 'px'; } function handleEnd() { if (!isDragging) return; voiceBtn.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)'; // Save position if moved if (hasMoved) { const rect = voiceBtn.getBoundingClientRect(); savePosition(rect.left, rect.top); } isDragging = false; // Small delay to prevent click event if dragged if (hasMoved) { setTimeout(function() { hasMoved = false; }, 100); } } // Mouse events voiceBtn.addEventListener('mousedown', function(e) { if (e.button !== 0) return; e.preventDefault(); handleStart(e.clientX, e.clientY); }); document.addEventListener('mousemove', function(e) { handleMove(e.clientX, e.clientY); }); document.addEventListener('mouseup', handleEnd); // Touch events voiceBtn.addEventListener('touchstart', function(e) { // Don't prevent default - let the click handler work handleStart(e.touches[0].clientX, e.touches[0].clientY); }, { passive: true }); document.addEventListener('touchmove', function(e) { if (isDragging) { e.preventDefault(); // Only prevent during actual drag handleMove(e.touches[0].clientX, e.touches[0].clientY); } }, { passive: false }); document.addEventListener('touchend', handleEnd); // Handle window resize to keep button visible window.addEventListener('resize', function() { const currentLeft = parseInt(voiceBtn.style.left) || 0; const currentTop = parseInt(voiceBtn.style.top) || 0; const maxLeft = window.innerWidth - voiceBtn.offsetWidth; const maxTop = window.innerHeight - voiceBtn.offsetHeight; const newLeft = Math.max(0, Math.min(currentLeft, maxLeft)); const newTop = Math.max(0, Math.min(currentTop, maxTop)); if (newLeft !== currentLeft || newTop !== currentTop) { voiceBtn.style.left = newLeft + 'px'; voiceBtn.style.top = newTop + 'px'; savePosition(newLeft, newTop); } }); // Click handler - csak akkor initál, ha NEM volt drag voiceBtn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); if (hasMoved) { return; } // First, ensure the audio context is active (crucial for mobile) ensureAudioContext().then(function() { // Voice chat toggle logic if (voiceBtn.classList.contains('voice-active')) { // Stop voice if (typeof window.fgptVoiceGlobal !== 'undefined' && window.fgptVoiceGlobal.running) { window.fgptVoiceGlobal.stop(); } } else { // Start voice on current page initGlobalVoice(); } }); }); // Listen for voice state changes if (typeof window.addEventListener !== 'undefined') { window.addEventListener('fgpt-voice-started', function() { voiceBtn.classList.add('voice-active'); var label = voiceBtn.querySelector('.fgpt-voice-label'); if (label) { label.textContent = label.getAttribute('data-active-text') || '结束通话'; } }); window.addEventListener('fgpt-voice-stopped', function() { voiceBtn.classList.remove('voice-active'); var label = voiceBtn.querySelector('.fgpt-voice-label'); if (label) { label.textContent = label.getAttribute('data-inactive-text') || '货运GPT调用'; } // Hide action buttons when call ends hideActionButtons(); }); } // Global voice initialization for non-chat pages function initGlobalVoice() { // Security check: Microphone access requires HTTPS if (window.location.protocol !== 'https:') { alert('建立安全连接(HTTPS)以进行语音通话。'); return; } // Create global voice object if it doesn't exist if (typeof window.fgptVoiceGlobal === 'undefined') { window.fgptVoiceGlobal = { running: false, peerConnection: null, dataChannel: null, audioElement: null, timerInterval: null, startTime: null, ringingAudio: null, confirmedEmail: null, // Track the last confirmed email greeted: false // Prevent double greeting }; } // Reset greeted flag for new call window.fgptVoiceGlobal.greeted = false; // Use the global AudioContext var audioContext = window.fgptAudioContext; var ringingInterval; function playRingingTone() { // Ensure context is running before playing sound if (audioContext.state === 'suspended') { audioContext.resume().then(function() { actuallyPlayRingingTone(); }); } else { actuallyPlayRingingTone(); } } function actuallyPlayRingingTone() { var oscillator = audioContext.createOscillator(); var gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.frequency.value = 440; // A4 note gainNode.gain.setValueAtTime(0.3, audioContext.currentTime); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.5); } // Play ringing every 2 seconds playRingingTone(); ringingInterval = setInterval(playRingingTone, 2000); // Get ephemeral token from server fetch('https://fuvarborze.hu/modules/dataimport/ajax.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=voice_session' }) .then(function(response) { return response.json(); }) .then(function(data) { if (!data.ok || !data.token) { clearInterval(ringingInterval); alert('无法启动语音对话'); console.error('Session error:', data); return; } var ephemeralKey = data.token; // Request microphone access first navigator.mediaDevices.getUserMedia({ audio: true }) .then(function(stream) { var pc = new RTCPeerConnection(); window.fgptVoiceGlobal.peerConnection = pc; // Set up audio element var audioEl = document.createElement('audio'); audioEl.autoplay = true; audioEl.playbackRate = 1.1; // 110% speed window.fgptVoiceGlobal.audioElement = audioEl; // PAUSE inactivity timer when AI starts speaking audioEl.addEventListener('play', function() { if (typeof window.pauseInactivityTimer === 'function') { window.pauseInactivityTimer(); } }); // RESUME inactivity timer when AI stops speaking audioEl.addEventListener('pause', function() { if (typeof window.resumeInactivityTimer === 'function') { window.resumeInactivityTimer(); } }); audioEl.addEventListener('ended', function() { if (typeof window.resumeInactivityTimer === 'function') { window.resumeInactivityTimer(); } }); pc.ontrack = function(e) { audioEl.srcObject = e.streams[0]; // Ensure playback rate is applied after stream is set audioEl.playbackRate = 1.1; }; // Add local audio track from microphone stream.getTracks().forEach(function(track) { pc.addTrack(track, stream); }); // Create data channel var dc = pc.createDataChannel('oai-events'); window.fgptVoiceGlobal.dataChannel = dc; dc.onopen = function() { // Stop ringing and play connection beep clearInterval(ringingInterval); var beepOsc = audioContext.createOscillator(); var beepGain = audioContext.createGain(); beepOsc.connect(beepGain); beepGain.connect(audioContext.destination); beepOsc.frequency.value = 800; beepGain.gain.setValueAtTime(0.2, audioContext.currentTime); beepOsc.start(audioContext.currentTime); beepOsc.stop(audioContext.currentTime + 0.25); window.fgptVoiceGlobal.running = true; window.fgptVoiceGlobal.startTime = Date.now(); window.dispatchEvent(new Event('fgpt-voice-started')); // Start timer var timerEl = document.querySelector('.fgpt-voice-timer'); window.fgptVoiceGlobal.timerInterval = setInterval(function() { var elapsed = Math.floor((Date.now() - window.fgptVoiceGlobal.startTime) / 1000); var minutes = Math.floor(elapsed / 60); var seconds = elapsed % 60; if (timerEl) { timerEl.textContent = (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds; } }, 1000); // Get page context for dynamic instructions var pageTitle = document.title || ''; var pageDesc = ''; var metaDesc = document.querySelector('meta[name="description"]'); if (metaDesc) pageDesc = metaDesc.getAttribute('content') || ''; var pageContext = ''; if (pageTitle) pageContext += 'Az oldal címe: ' + pageTitle + '. '; if (pageDesc) pageContext += 'Az oldal leírása: ' + pageDesc + '. '; // Build comprehensive system instructions var instructions = `Te vagy a Fuvarbörze freightGPT hangalapú asszisztense. ALAPSZABÁLYOK: - MAGYAR nyelv! Whisper néha rosszul fordít - értelmezd magyarként! - RÖVID válaszok! Max 2-3 mondat! - NE ismételd vissza amit mondtak! - NE magyarázd a számítást! Csak az eredményt mondd! - MAGÁZZ! (Ön, Önnek) - "Ft" helyett mondd: "forint" (mert "font"-nak hangzik) - Számokat mondd ki: "százhúszezer forint nettó" Felhasználó NINCS bejelentkezve - email kell ajánlatkéréshez! ═══════════════════════════════════════════════════════════════ KRITIKUS: KALKULÁCIÓ ≠ AJÁNLATKÉRÉS! KÜLÖNBÖZŐ DOLGOK! ═══════════════════════════════════════════════════════════════ KALKULÁCIÓ = csak árat mondasz, NEM kérdezel ÁSZF-et, NEM kérsz email-t! AJÁNLATKÉRÉS = fuvarozókat értesítünk, EHHEZ kell ÁSZF + email! Ha "kalkuláció", "mennyi lenne", "mi az ára" → CSAK számolj és mondd az árat! Ha "ajánlatkérés", "fuvarozót keresek", "fel akarom adni" → AKKOR kérdezz ÁSZF-et! KALKULÁCIÓ FOLYAMATA (NEM kell ÁSZF!): 1. Kérdezd: Honnan-hová? 2. Kérdezd: Mit szállít, mennyi kg? 3. Számold ki az árat → Mondd az eredményt! 4. Utána kérdezd: "Szeretne ajánlatkérést is? Díjmentes!" - Ha NEM → kész, köszönj el! - Ha IGEN → AKKOR jön az ÁSZF kérdés! ═══ JÁRMŰ KAPACITÁS - KÖTELEZŐ SZABÁLY! ═══ NAGYON FONTOS MAGYARÁZAT: A járművek neve (3,5t, 7,5t, 12t, stb.) az ÖSSZTÖMEGET jelenti, NEM a szállítható rakományt! A 3,5 tonnás furgon NEM 3500 kg-ot tud szállítani! A 3,5 tonna az a jármű + a sofőr + az üzemanyag + a rakomány EGYÜTTES súlya! Ebből következik, hogy egy 3,5 tonnás furgon valós szállítási kapacitása csak kb. 1000-1200 kg. Ha valaki 1500 kg-ot akar szállítani, az NEM fér be egy 3,5 tonnás furgonba! Ahhoz 7,5 tonnás teherautó kell! KAPACITÁSOK: - 3,5t furgon: max 1000 kg, max 6 raklap (a jármű maga ~2500 kg) - 7,5t teherautó: max 2500 kg, max 14 raklap - 12t teherautó: max 5500 kg, max 18 raklap - 18t teherautó: max 9500 kg, max 22 raklap - 24t kamion: max 23000 kg, max 33 raklap DÖNTÉSI SZABÁLY: Mindig a NAGYOBB szempont számít! Ha a súly VAGY a raklapszám meghaladja a limitet, nagyobb jármű kell! PÉLDÁK: - 800 kg, 4 raklap → 3,5t OK - 1200 kg, 4 raklap → 7,5t KELL (mert 1200 > 1000!) - 600 kg, 8 raklap → 7,5t KELL (mert 8 > 6 raklap!) - 1500 kg, 8 raklap → 7,5t KELL (mindkettő meghaladja a 3,5t limitet!) SÚLY ALAPJÁN: - 0-1000 kg → 3,5t - 1001-2500 kg → 7,5t (3,5t NEM JÓ!) - 2501-5500 kg → 12t - 5501-9500 kg → 18t - 9501+ kg → 24t RAKLAP ALAPJÁN: - 1-6 raklap → 3,5t - 7-14 raklap → 7,5t (3,5t NEM JÓ!) - 15-18 raklap → 12t - 19-22 raklap → 18t - 23+ raklap → 24t ═══ ÁRAK ═══ 0-150 km = ÁTALÁNY: 3,5t: 55-70 ezer | 7,5t: 75-95 ezer | 12t: 95-120 ezer | 18t: 120-150 ezer | 24t: 145-180 ezer 150-300 km = km × díj: 3,5t: 360 Ft/km | 7,5t: 520 Ft/km | 12t: 600 Ft/km | 18t: 650 Ft/km | 24t: 800 Ft/km 300+ km = km × díj: 3,5t: 310 Ft/km | 7,5t: 460 Ft/km | 12t: 520 Ft/km | 18t: 570 Ft/km | 24t: 670 Ft/km PÉLDA: Hatvan-Sopron (280 km), 7,5t: → "Körülbelül százötven-százhatvanezer forint nettó. De ajánlatkéréssel olcsóbb lehet!" ═══ AJÁNLATKÉRÉS MOTIVÁCIÓ - NAGYON FONTOS! ═══ Kalkuláció után MINDIG erőteljesen ajánld az ajánlatkérést! Így mondd: "Ez a piaci átlagár. DE! Ha létrehoz egy díjmentes ajánlatkérést a Fuvarbörze-n, akár 20-30%-kal olcsóbb ajánlatot is kaphat! Miért? Mert olyan fuvarozókat találunk, akiknek PONT AZON AZ ÚTVONALON van visszfuvarjuk - nekik megéri olcsóbban vinni, mint üresen menni haza. Létrehozzam? Teljesen díjmentes és nem kötelez semmire!" RÖVID VERZIÓ (ha nincs idő): "Ajánlatkéréssel akár 30%-kal olcsóbb is lehet, mert találunk visszfuvarost! Díjmentes, létrehozzam?" ELŐNYÖK amiket hangsúlyozz: - DÍJMENTES az ajánlatkérés - NEM kötelez semmire - Akár 20-30%-kal OLCSÓBB lehet visszfuvarban - Több fuvarozó versenyez az Ön fuvarjáért - 24 órán belül kaphat ajánlatokat ═══ AJÁNLATKÉRÉS FOLYAMATA ═══ 1. "Elfogadja az ÁSZF-et?" - VÁRJ válaszra! 2. "Mondja be az email címét!" - "kukac"=@ "pont"=. 3. "Létrehozzam?" - csak IGEN után hívd a create_freight_request-et! Mai dátum: 2026-07-24`; // Send session configuration var sessionConfig = { type: 'session.update', session: { modalities: ['text', 'audio'], instructions: instructions, voice: 'alloy', input_audio_format: 'pcm16', output_audio_format: 'pcm16', input_audio_transcription: { model: 'whisper-1' }, turn_detection: { type: 'server_vad', threshold: 0.5, prefix_padding_ms: 300, silence_duration_ms: 500 }, tools: [{ type: 'function', name: 'create_freight_request', description: 'Létrehoz egy fuvar ajánlatkérést. Az irányítószámokat, koordinátákat és távolságot TE állapítsd meg a város neve alapján - NE kérdezd a felhasználót!', parameters: { type: 'object', properties: { email: { type: 'string', description: 'Felhasználó email címe - KÖTELEZŐ!' }, user_id: { type: 'number', description: 'Felhasználó ID ha be van jelentkezve' }, pickup_location: { type: 'string', description: 'Felrakodás helye (város) - KÖTELEZŐ!' }, pickup_location_zip: { type: 'string', description: 'Felrakodás irányítószáma - TE állapítsd meg a város alapján! (pl. Hatvan=3000, Gödöllő=2100, Budapest=1xxx)' }, unload_location: { type: 'string', description: 'Lerakodás helye (város) - KÖTELEZŐ!' }, unload_location_zip: { type: 'string', description: 'Lerakodás irányítószáma - TE állapítsd meg a város alapján!' }, pickup_country_code: { type: 'string', description: 'Felrakodás országkódja', default: 'HU' }, unload_country_code: { type: 'string', description: 'Lerakodás országkódja', default: 'HU' }, pickup_lat: { type: 'number', description: 'Felrakodás GPS lat - TE számítsd ki a város alapján!' }, pickup_lng: { type: 'number', description: 'Felrakodás GPS lng - TE számítsd ki a város alapján!' }, unload_lat: { type: 'number', description: 'Lerakodás GPS lat - TE számítsd ki a város alapján!' }, unload_lng: { type: 'number', description: 'Lerakodás GPS lng - TE számítsd ki a város alapján!' }, utvonal_hossza_km: { type: 'number', description: 'Útvonal hossza km-ben - TE számítsd ki a városok alapján!' }, weight: { type: 'number', description: 'Súly kg-ban - KÖTELEZŐ!' }, quantity: { type: 'number', description: 'Mennyiség - KÖTELEZŐ!' }, quantity_unit: { type: 'string', description: 'Mennyiség egysége', default: 'db' }, cargo_type_name: { type: 'string', description: 'Rakomány típusa', default: 'általános áruszállítás' }, cargo_type_rkat: { type: 'number', description: 'Rakomány kategória ID', default: 1 }, pickup_date_from: { type: 'string', description: 'Felrakodás dátuma YYYY-MM-DD - KÖTELEZŐ!' }, pickup_date_to: { type: 'string', description: 'Felrakodás dátuma vége YYYY-MM-DD' }, unload_date_from: { type: 'string', description: 'Lerakodás dátuma YYYY-MM-DD' }, unload_date_to: { type: 'string', description: 'Lerakodás dátuma vége YYYY-MM-DD' }, additional_info: { type: 'string', description: 'További információk' }, turns: { type: 'number', description: 'Fordulók száma', default: 1 } }, required: ['email', 'pickup_location', 'unload_location', 'weight', 'quantity', 'pickup_date_from'] } }], tool_choice: 'auto', max_response_output_tokens: 1000, // ~50-60 mp beszéd temperature: 0.7 } }; dc.send(JSON.stringify(sessionConfig)); // AZONNAL küldjük a köszöntést - ne várjunk a felhasználóra! // De csak egyszer - flag-gel védjük a dupla futást if (!window.fgptVoiceGlobal.greeted) { window.fgptVoiceGlobal.greeted = true; setTimeout(function() { // Köszöntő üzenet küldése - pontos szöveggel var greetingMsg = { type: 'conversation.item.create', item: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'Mondd: "Üdvözlöm! Ha fuvardíj kalkulációt szeretne készíteni, állok rendelkezésére, de más kérdésekre is szívesen válaszolok." - csak ezt az egy mondatot mondd, semmi mást!' }] } }; dc.send(JSON.stringify(greetingMsg)); dc.send(JSON.stringify({ type: 'response.create' })); }, 300); } }; // Helper function to save voice messages to database // KIKAPCSOLVA - a Whisper rossz nyelven írja át a magyar beszédet function saveVoiceMessage(message, sender) { // Mentés kikapcsolva mert rossz nyelvű átiratokat generál return; /* if (!message || message.trim() === '') return; fetch('https://fuvarborze.hu/modules/voicegpt/save_voice_message.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'message=' + encodeURIComponent(message) + '&sender=' + encodeURIComponent(sender) }).catch(function(err) { // Silent fail - don't interrupt voice chat }); */ } // Listen for AI messages to detect email request and JSON responses dc.onmessage = function(event) { try { var msg = JSON.parse(event.data); // console.log('[Voice] Received message type:', msg.type); // Reset inactivity timer on any activity if (typeof window.resetInactivityTimer === 'function') { window.resetInactivityTimer(); } // Save user input transcription to database if (msg.type === 'conversation.item.input_audio_transcription.completed') { var userTranscript = msg.transcript || ''; if (userTranscript.trim() !== '') { console.log('[Voice] USER said:', userTranscript); saveVoiceMessage(userTranscript, 'user'); } } // Handle function calls if (msg.type === 'response.function_call_arguments.done') { // console.log('[Voice] Function call received:', msg.name); // console.log('[Voice] Raw arguments string:', msg.arguments); if (msg.name === 'create_freight_request') { try { var args = JSON.parse(msg.arguments); // console.log('[Voice] Parsed function arguments:', args); // Extract email from nested structure if AI sent it that way var emailFromArgs = args.email || (args.fuvar_ajanlatkeres && args.fuvar_ajanlatkeres.userdata && args.fuvar_ajanlatkeres.userdata[0] && args.fuvar_ajanlatkeres.userdata[0].email) || ''; // Use the last confirmed email if available (this ensures we use the corrected email) var finalEmail = window.fgptVoiceGlobal.confirmedEmail || emailFromArgs; // console.log('[Voice] Email from args:', emailFromArgs); // console.log('[Voice] Confirmed email from global:', window.fgptVoiceGlobal.confirmedEmail); // console.log('[Voice] Final email to use:', finalEmail); // console.log('[Voice] All args keys:', Object.keys(args)); // Update email in the structure if AI already structured it if (args.fuvar_ajanlatkeres) { // Update the email with the confirmed one if (!args.fuvar_ajanlatkeres.userdata) { args.fuvar_ajanlatkeres.userdata = [{}]; } if (!args.fuvar_ajanlatkeres.userdata[0]) { args.fuvar_ajanlatkeres.userdata[0] = {}; } args.fuvar_ajanlatkeres.userdata[0].email = finalEmail; // console.log('[Voice] Processing freight request from function call with updated email:', args); // console.log('[Voice] JSON to send:', JSON.stringify(args)); // Send directly to backend fetch('https://fuvarborze.hu/modules/dataimport/ajax.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=process_freight_request&json_data=' + encodeURIComponent(JSON.stringify(args)) }) .then(function(response) { // console.log('[Voice] Backend response status:', response.status); if (!response.ok) { return response.text().then(function(text) { console.error('[Voice] Backend error response:', text); throw new Error('Backend returned ' + response.status + ': ' + text); }); } return response.json(); }) .then(function(data) { // console.log('[Voice] Backend response:', data); var dc = window.fgptVoiceGlobal.dataChannel; if (data.success) { // console.log('✅ Ajánlatkérés sikeresen létrehozva:', data); // Hide email input on success hideEmailInput(); // Send success response back to AI dc.send(JSON.stringify({ type: 'conversation.item.create', item: { type: 'function_call_output', call_id: msg.call_id, output: JSON.stringify({ success: true, message: 'Az ajánlatkérés sikeresen létrehozva! Azonosító: ' + (data.request_id || 'N/A') }) } })); // Trigger response generation dc.send(JSON.stringify({ type: 'response.create' })); } else { console.error('❌ Ajánlatkérés hiba:', data.error); // Send error back to AI for re-prompting var errorMsg = 'HIBA: ' + (data.message || data.error) + ' Kérem javítsa és próbálja újra!'; dc.send(JSON.stringify({ type: 'conversation.item.create', item: { type: 'function_call_output', call_id: msg.call_id, output: JSON.stringify({ success: false, error: data.error, message: errorMsg }) } })); // Trigger response generation dc.send(JSON.stringify({ type: 'response.create' })); } }) .catch(function(err) { console.error('[Voice] Backend error:', err); var dc = window.fgptVoiceGlobal.dataChannel; dc.send(JSON.stringify({ type: 'conversation.item.create', item: { type: 'function_call_output', call_id: msg.call_id, output: JSON.stringify({ success: false, error: 'Technikai hiba történt a mentés során: ' + err.message }) } })); dc.send(JSON.stringify({ type: 'response.create' })); }); return; // Exit early } // Build the freight request JSON (fallback if not structured) var freightRequest = { fuvar_ajanlatkeres: { userdata: [{ email: finalEmail // Use the confirmed email }], pickup_location: args.pickup_location, pickup_location_zip: args.pickup_location_zip || '', unload_location: args.unload_location, unload_location_zip: args.unload_location_zip || '', pickup_country_code: args.pickup_country_code || 'HU', unload_country_code: args.unload_country_code || 'HU', pickup_coordinates: { lat: args.pickup_lat || 0, lng: args.pickup_lng || 0 }, unload_coordinates: { lat: args.unload_lat || 0, lng: args.unload_lng || 0 }, utvonal_hossza_km: args.utvonal_hossza_km || 0, weight: args.weight, quantity: args.quantity, quantity_unit: args.quantity_unit || 'raklap', cargo_type: {}, pickup_date_from: args.pickup_date_from, pickup_date_to: args.pickup_date_to || args.pickup_date_from, unload_date_from: args.unload_date_from || args.pickup_date_from, unload_date_to: args.unload_date_to || args.pickup_date_from, additional_info: args.additional_info || '', turns: args.turns || 1 } }; // Add user_id if provided if (args.user_id) { freightRequest.fuvar_ajanlatkeres.userdata[0].user_id = args.user_id; freightRequest.fuvar_ajanlatkeres.user_id = args.user_id; } // Add cargo type if (args.cargo_type_name && args.cargo_type_rkat) { freightRequest.fuvar_ajanlatkeres.cargo_type[args.cargo_type_name] = { rkat: args.cargo_type_rkat }; } // console.log('[Voice] Processing freight request from function call:', freightRequest); // Send to backend fetch('https://fuvarborze.hu/modules/dataimport/ajax.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=process_freight_request&json_data=' + encodeURIComponent(JSON.stringify(freightRequest)) }) .then(function(response) { return response.json(); }) .then(function(data) { // console.log('[Voice] Backend response:', data); if (data.success) { // console.log('✅ Ajánlatkérés sikeresen létrehozva'); // Hide email input on success hideEmailInput(); // Send function response back to AI var funcResponse = { type: 'conversation.item.create', item: { type: 'function_call_output', call_id: msg.call_id, output: JSON.stringify({success: true}) } }; dc.send(JSON.stringify(funcResponse)); dc.send(JSON.stringify({ type: 'response.create' })); } else { console.error('❌ Ajánlatkérés hiba:', data.error); // Handle validation errors - send error back to AI if (data.validation_error) { var errorMsg = { type: 'conversation.item.create', item: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'HIBA: ' + data.message + ' Kérem javítsa és próbálja újra!' }] } }; dc.send(JSON.stringify(errorMsg)); dc.send(JSON.stringify({ type: 'response.create' })); } } }) .catch(function(err) { console.error('Backend error:', err); }); } catch(e) { console.error('Function call parse error:', e); } } } // Check for transcript or text output if (msg.type === 'response.audio_transcript.done' || msg.type === 'response.text.done' || msg.type === 'conversation.item.created') { var text = ''; var originalText = ''; if (msg.transcript) { text = msg.transcript; originalText = msg.transcript; } else if (msg.text) { text = msg.text; originalText = msg.text; } else if (msg.item && msg.item.content) { msg.item.content.forEach(function(c) { if (c.transcript) { text += c.transcript; originalText += c.transcript; } if (c.text) { text += c.text; originalText += c.text; } }); } // console.log('[Voice] Original text:', originalText.substring(0, 200)); // Save AI response to database (only for completed transcripts) if (msg.type === 'response.audio_transcript.done' && originalText.trim() !== '') { console.log('[Voice] AI said:', originalText); saveVoiceMessage(originalText, 'assistant'); } // Get lowercase version for all detections var textLower = originalText.toLowerCase(); // Detect goodbye phrases and auto-close var goodbyePhrases = ['viszlát', 'viszontlátásra', 'búcsúzom', 'kellemes napot', 'szép napot', 'legyen szép napja', 'további szép napot', 'sikeres fuvar', 'bármiben segíthetek', 'ha bármi kérdése', 'bye', 'goodbye', 'take care', 'see you']; // Check if the message contains farewell phrase // Allow longer messages (up to 200 chars) as AI sometimes adds extra text var hasGoodbye = false; if (textLower.length < 200) { hasGoodbye = goodbyePhrases.some(function(phrase) { return textLower.includes(phrase); }); } if (hasGoodbye && window.fgptVoiceGlobal && window.fgptVoiceGlobal.running) { console.log('[Voice] Goodbye detected, closing call in 5 seconds...'); setTimeout(function() { if (window.fgptVoiceGlobal && window.fgptVoiceGlobal.running) { window.fgptVoiceGlobal.stop(); } }, 5000); // Give 5 seconds for goodbye message to finish } // Reset inactivity timer on any message if (window.fgptVoiceGlobal && window.fgptVoiceGlobal.running) { if (typeof window.resetInactivityTimer === 'function') { window.resetInactivityTimer(); } } // Detect keywords and show relevant action buttons var buttonsToShow = []; if (textLower.includes('onmap') || textLower.includes('térképes') || textLower.includes('körfuvar')) { buttonsToShow.push({ label: 'OnMap', url: 'https://fuvarborze.hu/?link=onmap' }); } if (textLower.includes('dataimport') || textLower.includes('tömeges') || textLower.includes('fájl')) { buttonsToShow.push({ label: 'DataImport', url: 'https://fuvarborze.hu/modules/dataimport/' }); } if (textLower.includes('fuvarajánlat') || textLower.includes('tender') || textLower.includes('ajánlatot tehet')) { buttonsToShow.push({ label: 'Fuvarajánlatok', url: 'https://fuvarborze.hu/?link=tender_list' }); } if (textLower.includes('állandó útvonal') || textLower.includes('visszfuvar') || textLower.includes('raktérbörze')) { buttonsToShow.push({ label: 'Állandó útvonalak', url: 'https://fuvarborze.hu/?link=rakterborze' }); } if (textLower.includes('kalkuláció') || textLower.includes('fuvardíj') || textLower.includes('árajánlat')) { buttonsToShow.push({ label: 'Fuvardíj kalkuláció', url: 'https://fuvarborze.hu/?link=calc' }); } // Show buttons if any detected if (buttonsToShow.length > 0) { showActionButtons(buttonsToShow); } else if (currentActionButtons.length > 0) { // Hide buttons after 10 seconds if new topic setTimeout(function() { if (!textLower.includes('onmap') && !textLower.includes('dataimport') && !textLower.includes('fuvarajánlat') && !textLower.includes('állandó') && !textLower.includes('kalkuláció')) { hideActionButtons(); } }, 10000); } // Check for JSON in response (ajánlatkérés or unsubscribe) // Try to find complete JSON object (handle nested structures) var jsonMatch = null; var jsonData = null; // Look for JSON patterns starting with { and containing expected keys if (originalText.includes('fuvar_ajanlatkeres') || originalText.includes('unsubscribe')) { // console.log('[Voice] Found JSON keyword, attempting to parse...'); // Find the start of JSON var startIdx = originalText.indexOf('{'); if (startIdx !== -1) { // Try to parse from each { position for (var i = startIdx; i < originalText.length; i++) { if (originalText[i] === '{') { // Try to parse from this position to the end var substring = originalText.substring(i); // Find matching closing brace by counting var depth = 0; var endIdx = -1; for (var j = 0; j < substring.length; j++) { if (substring[j] === '{') depth++; else if (substring[j] === '}') { depth--; if (depth === 0) { endIdx = j; break; } } } if (endIdx !== -1) { var candidate = substring.substring(0, endIdx + 1); try { var parsed = JSON.parse(candidate); if (parsed.fuvar_ajanlatkeres || parsed.unsubscribe) { jsonMatch = candidate; jsonData = parsed; // console.log('Found valid JSON:', jsonMatch); break; } } catch(e) { // Not valid JSON, continue } } } } } } if (jsonData) { // Check if it's a freight request if (jsonData.fuvar_ajanlatkeres) { // console.log('Processing freight request:', jsonData); // Send JSON to backend for processing fetch('https://fuvarborze.hu/modules/dataimport/ajax.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=process_freight_request&json_data=' + encodeURIComponent(jsonMatch) }) .then(function(response) { return response.json(); }) .then(function(data) { if (data.success) { // console.log('Ajánlatkérés sikeresen létrehozva:', data); // Hide email input if shown hideEmailInput(); } else { // console.error('Ajánlatkérés hiba:', data.error); } }) .catch(function(err) { // console.error('Backend error:', err); }); } // Check if it's an unsubscribe request if (jsonData.unsubscribe) { fetch('https://fuvarborze.hu/modules/dataimport/ajax.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=process_unsubscribe&json_data=' + encodeURIComponent(jsonMatch) }) .then(function(response) { return response.json(); }) .then(function(data) { // console.log('Unsubscribe processed:', data); }); } } text = text.toLowerCase(); // Detect email request in AI response if (text.includes('email') || text.includes('e-mail') || text.includes('@')) { // Try to extract email from text var emailMatch = text.match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/); var detectedEmail = emailMatch ? emailMatch[0] : ''; // Show email input panel showEmailInput(detectedEmail); // Set callback for when user confirms email emailConfirmCallback = function(confirmedEmail) { // Store confirmed email globally window.fgptVoiceGlobal.confirmedEmail = confirmedEmail; // console.log('[Voice] Email confirmed and stored:', confirmedEmail); // Send confirmed email back to AI var emailMsg = { type: 'conversation.item.create', item: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'Az email címem: ' + confirmedEmail }] } }; dc.send(JSON.stringify(emailMsg)); dc.send(JSON.stringify({ type: 'response.create' })); }; } } } catch(e) { // Ignore parse errors } }; dc.onclose = function() { window.fgptVoiceGlobal.running = false; window.dispatchEvent(new Event('fgpt-voice-stopped')); // Stop microphone tracks stream.getTracks().forEach(function(track) { track.stop(); }); }; dc.onerror = function(err) { console.error('DataChannel error:', err); window.fgptVoiceGlobal.running = false; window.dispatchEvent(new Event('fgpt-voice-stopped')); }; // Create and set offer pc.createOffer().then(function(offer) { return pc.setLocalDescription(offer); }).then(function() { return fetch('https://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-12-17', { method: 'POST', headers: { 'Authorization': 'Bearer ' + ephemeralKey, 'Content-Type': 'application/sdp' }, body: pc.localDescription.sdp }); }).then(function(response) { return response.text(); }).then(function(answerSdp) { return pc.setRemoteDescription({ type: 'answer', sdp: answerSdp }); }).catch(function(err) { console.error('Voice init error:', err); alert('启动语音通话时发生错误'); window.fgptVoiceGlobal.running = false; window.dispatchEvent(new Event('fgpt-voice-stopped')); }); }) .catch(function(err) { console.error('Microphone access denied:', err); alert('请允许使用麦克风进行语音通话!'); }); }) .catch(function(err) { console.error('Session error:', err); alert('无法启动语音对话'); }); } // Global voice stop function window.fgptVoiceGlobal = window.fgptVoiceGlobal || {}; window.fgptVoiceGlobal.stop = function() { // Stop timer if (window.fgptVoiceGlobal.timerInterval) { clearInterval(window.fgptVoiceGlobal.timerInterval); window.fgptVoiceGlobal.timerInterval = null; } // Reset timer display var timerEl = document.querySelector('.fgpt-voice-timer'); if (timerEl) timerEl.textContent = '00:00'; if (window.fgptVoiceGlobal.dataChannel) { window.fgptVoiceGlobal.dataChannel.close(); } if (window.fgptVoiceGlobal.peerConnection) { // Stop all tracks before closing connection window.fgptVoiceGlobal.peerConnection.getSenders().forEach(function(sender) { if (sender.track) { sender.track.stop(); } }); window.fgptVoiceGlobal.peerConnection.close(); } if (window.fgptVoiceGlobal.audioElement) { window.fgptVoiceGlobal.audioElement.srcObject = null; } window.fgptVoiceGlobal.running = false; window.dispatchEvent(new Event('fgpt-voice-stopped')); }; // Publikus API – külső gombok számára window.fgptStartVoiceCall = function() { ensureAudioContext().then(function() { if (window.fgptVoiceGlobal && window.fgptVoiceGlobal.running) { window.fgptVoiceGlobal.stop(); } else { initGlobalVoice(); } }); }; })(); </script> </div> </div> </div> <button type="button" class="help-badge-btn" onclick="toggleHelpPopup()"> <span class="icon">💬</span> <span>需要帮助吗?</span> </button> </div> <script> function toggleHelpPopup() { document.getElementById('helpPopup').classList.toggle('show'); } function submitHelpForm() { var message = document.getElementById('helpMessage').value.trim(); var btn = document.getElementById('helpSubmitBtn'); if (!message) { alert('请留下您的消息!'); return; } // Disable gomb és loader megjelenítése btn.disabled = true; btn.innerHTML = '<span class="help-loader"></span> 正在打开……'; // FreightGPT modal megnyitása az üzenettel if (typeof openFreightGPTModal === 'function') { document.getElementById('helpPopup').classList.remove('show'); document.getElementById('helpMessage').value = ''; btn.disabled = false; btn.innerHTML = '⌲ 消息发送'; openFreightGPTModal(message, '需要帮助吗?'); } else { // Fallback: átirányítás a chat oldalra window.location.href = 'https://fuvarborze.hu/zh/chat/?new=1&prompt=' + encodeURIComponent(message); } } // Bezárás kívülre kattintáskor document.addEventListener('click', function(e) { var badge = document.getElementById('helpBadge'); if (badge && !badge.contains(e.target)) { document.getElementById('helpPopup').classList.remove('show'); } }); </script> <style> /* ── Ticker sáv ── */ #site-ticker { position: fixed; bottom: 0; left: 0; width: 100%; height: 28px; z-index: 99999; background: rgba(8, 12, 26, 0.92); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); border-top: 1px solid rgba(255,255,255,0.08); display: flex; align-items: center; overflow: hidden; font-size: 12px; color: #e8e8e8; user-select: none; } #site-ticker .ticker-label { flex-shrink: 0; padding: 0 10px; font-weight: 700; font-size: 11px; letter-spacing: 0.08em; color: #fff; background: rgba(23, 159, 220, 0.85); height: 100%; display: flex; align-items: center; white-space: nowrap; border-right: 1px solid rgba(255,255,255,0.15); } #site-ticker .ticker-track-wrap { flex: 1; overflow: hidden; height: 100%; position: relative; } #site-ticker .ticker-track { display: inline-flex; align-items: center; height: 100%; white-space: nowrap; animation: tickerScroll 38s linear infinite; gap: 0; } #site-ticker .ticker-track:hover { animation-play-state: paused; } @keyframes tickerScroll { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } } #site-ticker .ti { display: inline-flex; align-items: center; gap: 4px; padding: 0 14px; border-right: 1px solid rgba(255,255,255,0.1); height: 100%; } #site-ticker .ti strong { color: #fff; font-weight: 700; } #site-ticker .ti-eur strong { color: #4fc3f7; } #site-ticker .ti-usd strong { color: #81d4fa; } #site-ticker .ti-diesel strong { color: #ffb74d; } #site-ticker .ti-live strong { color: #69f0ae; } #site-ticker .ti-sep { color: rgba(255,255,255,0.25); font-size: 0.9em; } #site-ticker .ticker-dot { display: inline-block; width: 6px; height: 6px; background: #69f0ae; border-radius: 50%; animation: tickerPulse 2s infinite; flex-shrink: 0; } @keyframes tickerPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } } /* Padding so content is not hidden behind ticker */ body { padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)) !important; } /* Mobile bottom navbar already above ticker because its z-index < 99999 */ </style> <div id="site-ticker" role="marquee" aria-label="Élő adatok"> <div class="ticker-label">📡 LIVE</div> <div class="ticker-track-wrap"> <div class="ticker-track" id="ticker-track"> <a href="https://fuvarborze.hu/zh/?link=statistics" class="ti ti-live" style="text-decoration:none;color:inherit;"> <span class="ticker-dot"></span> <span style="font-size:0.8em;opacity:0.7;margin-right:2px;">访客</span> 👥 <strong id="ticker-online">11</strong> 在线 <span class="ti-sep">·</span> 今天: <strong id="ticker-today">0</strong> </a> <a href="https://fuvarborze.hu/zh/?link=uzemanyag_arak" class="ti ti-diesel" style="text-decoration:none;color:inherit;"> <span style="font-size:0.8em;opacity:0.7;margin-right:2px;">柴油</span> ⛽ 🇩🇪 <strong class="ticker-diesel-val" data-country="DE">2,015</strong> 🇦🇹 <strong class="ticker-diesel-val" data-country="AT">1,840</strong> 🇮🇹 <strong class="ticker-diesel-val" data-country="IT">1,957</strong> 🇵🇱 <strong class="ticker-diesel-val" data-country="PL">1,612</strong> 🇭🇺 <strong class="ticker-diesel-val" data-country="HU">1,685</strong> <span style="font-size:0.82em;color:#aaa">€/L</span> </a> <span class="ti" style="padding-right:20px;"> 🚛 <a href="https://fuvarborze.hu/zh/freightlist/" style="color:#ffd54f;text-decoration:none;">货运报价</a> </span> <span class="ti"> 💼 <a href="https://fuvarborze.hu/zh/job-seeking-drivers/" style="color:#ce93d8;text-decoration:none;">司机职位</a> </span> <a href="https://fuvarborze.hu/zh/?link=statistics" class="ti ti-live" style="text-decoration:none;color:inherit;"> <span class="ticker-dot"></span> <span style="font-size:0.8em;opacity:0.7;margin-right:2px;">访客</span> 👥 <strong id="ticker-online">11</strong> 在线 <span class="ti-sep">·</span> 今天: <strong id="ticker-today">0</strong> </a> <a href="https://fuvarborze.hu/zh/?link=uzemanyag_arak" class="ti ti-diesel" style="text-decoration:none;color:inherit;"> <span style="font-size:0.8em;opacity:0.7;margin-right:2px;">柴油</span> ⛽ 🇩🇪 <strong class="ticker-diesel-val" data-country="DE">2,015</strong> 🇦🇹 <strong class="ticker-diesel-val" data-country="AT">1,840</strong> 🇮🇹 <strong class="ticker-diesel-val" data-country="IT">1,957</strong> 🇵🇱 <strong class="ticker-diesel-val" data-country="PL">1,612</strong> 🇭🇺 <strong class="ticker-diesel-val" data-country="HU">1,685</strong> <span style="font-size:0.82em;color:#aaa">€/L</span> </a> <span class="ti" style="padding-right:20px;"> 🚛 <a href="https://fuvarborze.hu/zh/freightlist/" style="color:#ffd54f;text-decoration:none;">货运报价</a> </span> <span class="ti"> 💼 <a href="https://fuvarborze.hu/zh/job-seeking-drivers/" style="color:#ce93d8;text-decoration:none;">司机职位</a> </span> <!-- duplicate for seamless loop --> </div> </div> </div> <script> (function() { function refreshTicker() { // GA4 live fetch('/ajaxjobs/analytics.php?action=live') .then(r => r.json()) .then(function(d) { var o = document.querySelectorAll('#ticker-online'); var t = document.querySelectorAll('#ticker-today'); o.forEach(function(el) { if (d.online !== undefined) el.textContent = d.online; }); t.forEach(function(el) { if (d.today !== undefined) el.textContent = d.today; }); }).catch(function(){}); // Árfolyam fetch('/ajaxjobs/exchange_rates.php') .then(r => r.json()) .then(function(d) { document.querySelectorAll('#ticker-eur').forEach(function(el) { if (d.eur) el.textContent = Math.round(d.eur).toLocaleString('hu-HU'); }); document.querySelectorAll('#ticker-usd').forEach(function(el) { if (d.usd) el.textContent = Math.round(d.usd).toLocaleString('hu-HU'); }); }).catch(function(){}); // Diesel fetch('/ajaxjobs/diesel_prices.php') .then(r => r.json()) .then(function(d) { if (!d.prices) return; document.querySelectorAll('.ticker-diesel-val[data-country]').forEach(function(el) { var code = el.dataset.country; if (d.prices[code]) el.textContent = d.prices[code].toFixed(3).replace('.', ','); }); }).catch(function(){}); } // Frissítés minden 2 percben setInterval(refreshTicker, 120000); })(); </script> <style> .fb-site-footer{background:linear-gradient(135deg,#0f172a 0%,#1e293b 50%,#0f172a 100%);padding:60px 20px 0;margin-top:60px;} .fb-site-footer .fb-footer-content{max-width:1200px;margin:0 auto;padding-bottom:40px;} .fb-site-footer .fb-footer-main{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:40px;padding-bottom:40px;border-bottom:1px solid rgba(255,255,255,0.1);} .fb-site-footer .fb-footer-brand h3{color:#fff;font-size:24px;font-weight:800;margin-bottom:16px;display:flex;align-items:center;gap:10px;} .fb-site-footer .fb-footer-brand h3 span{background:linear-gradient(135deg,#3b82f6,#8b5cf6);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;} .fb-site-footer .fb-footer-brand p{color:#cbd5e1;font-size:14px;line-height:1.7;margin-bottom:20px;} .fb-site-footer .fb-footer-contact-box{background:rgba(16,185,129,0.15);border:1px solid rgba(16,185,129,0.3);border-radius:12px;padding:16px;} .fb-site-footer .fb-footer-contact-box .contact-title{display:flex;align-items:center;gap:8px;color:#10b981;font-size:14px;font-weight:600;margin-bottom:8px;} .fb-site-footer .fb-footer-contact-box .contact-title .live-dot{width:8px;height:8px;background:#10b981;border-radius:50%;animation:pulse 1.5s infinite;} .fb-site-footer .fb-footer-contact-box a{display:block;color:#fff;font-size:16px;font-weight:700;text-decoration:none;margin-bottom:4px;} .fb-site-footer .fb-footer-contact-box a:hover{color:#3b82f6;} .fb-site-footer .fb-footer-contact-box .response-time{color:#cbd5e1;font-size:12px;} .fb-site-footer .fb-footer-col h4{color:#fff;font-size:16px;font-weight:700;margin-bottom:20px;} .fb-site-footer .fb-footer-col ul{list-style:none;padding:0;margin:0;} .fb-site-footer .fb-footer-col ul li{margin-bottom:12px;} .fb-site-footer .fb-footer-col ul li a{color:#cbd5e1;text-decoration:none;font-size:14px;transition:color 0.2s;display:inline-flex;align-items:center;gap:6px;} .fb-site-footer .fb-footer-col ul li a:hover{color:#3b82f6;} .fb-site-footer .fb-footer-bottom{padding:24px 0;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:16px;} .fb-site-footer .fb-footer-copyright{color:#64748b;font-size:13px;} .fb-site-footer .fb-footer-legal{display:flex;gap:24px;flex-wrap:wrap;} .fb-site-footer .fb-footer-legal a{color:#cbd5e1;text-decoration:none;font-size:13px;transition:color 0.2s;} .fb-site-footer .fb-footer-legal a:hover{color:#3b82f6;} @media(max-width:992px){.fb-site-footer .fb-footer-main{grid-template-columns:1fr 1fr;gap:32px;}.fb-site-footer .fb-footer-brand{grid-column:span 2;}} @media(max-width:600px){.fb-site-footer .fb-footer-main{grid-template-columns:1fr;}.fb-site-footer .fb-footer-brand{grid-column:span 1;}.fb-site-footer .fb-footer-legal{gap:12px;}} </style> <footer class="fb-site-footer"> <div class="fb-footer-content"> <div class="fb-footer-main"> <div class="fb-footer-brand"> <h3>🚚 Fuvar<span>Börze</span></h3> <p>匈牙利领先的货运市场,自2007年以来。我们连接委托人和可靠的货运公司,确保货物准时安全送达目的地。</p> <div class="fb-footer-contact-box"> <div class="contact-title"><span class="live-dot"></span>快速回应保证</div> <a href="mailto:hello@fuvarborze.hu">hello@fuvarborze.hu</a> <div class="response-time">平均回复时间:5分钟</div> </div> </div> <div class="fb-footer-col"> <h4>服务项目</h4> <ul> <li><a href="https://fuvarborze.hu/zh/submit-freight/">📦 货物运输</a></li> <li><a href="https://fuvarborze.hu/zh/moving-calculator/">🏠 搬家</a></li> <li><a href="https://fuvarborze.hu/zh/car-transport/">🚗 车辆运输</a></li> <li><a href="https://fuvarborze.hu/zh/freightlist/">📋 货运委托</a></li> <li><a href="https://fuvarborze.hu/zh/freight-cost-calculator/">🧮 计算器</a></li> </ul> </div> <div class="fb-footer-col"> <h4>货运公司</h4> <ul> <li><a href="https://fuvarborze.hu/zh/signin/">✨ 注册</a></li> <li><a href="https://fuvarborze.hu/zh/find-freight-offers/">🔍 货运报价</a></li> <li><a href="https://fuvarborze.hu/zh/submit-free-capacity/">🚛 容量申报</a></li> <li><a href="https://fuvarborze.hu/zh/job-offers-for-drivers/">👨‍✈️ 招聘信息</a></li> <li><a href="https://fuvarborze.hu/zh/chat/">💬 Böbe</a></li> </ul> </div> <div class="fb-footer-col"> <h4>公司简介</h4> <ul> <li><a href="https://fuvarborze.hu/zh/helpdesk/">❓ 帮助台</a></li> <li><a href="https://fuvarborze.hu/zh/?link=terms">条款与条件</a></li> <li><a href="https://fuvarborze.hu/zh/?link=adatvedelem">隐私政策</a></li> <li><a href="https://fuvarborze.hu/zh/?link=impresszum">关于我们</a></li> <li><a href="https://fuvarborze.hu/zh/affiliate-program/">合作伙伴计划</a></li> </ul> </div> </div> <div class="fb-footer-bottom"> <div class="fb-footer-copyright">© 2026 Fuvarbörze. 版权所有©</div> <div class="fb-footer-legal"> <a href="https://fuvarborze.hu/zh/?link=terms">通用条款与条件</a> <a href="https://fuvarborze.hu/zh/?link=adatvedelem">隐私政策</a> <a href="https://fuvarborze.hu/zh/?link=cookie">Cookie 政策</a> <a href="https://fuvarborze.hu/zh/?link=impresszum">关于我们</a> </div> </div> <div style="text-align:center;margin-top:18px;padding-top:16px;border-top:1px solid rgba(255,255,255,0.1);"> <a href="https://www.barion.com" target="_blank" rel="noopener noreferrer"> <img src="https://fuvarborze.hu/images/barion.png" alt="Barion biztonságos fizetés" style="max-height:36px;opacity:0.85;transition:opacity .2s;" onmouseover="this.style.opacity='1'" onmouseout="this.style.opacity='0.85'"> </a> </div> </div> </footer> <!-- Barion Pixel – Full event helpers --> <script> (function() { function makeArrayPrototypeSafeForBarion() { if (!Object.keys || !Object.defineProperty || !Object.getOwnPropertyDescriptor) return; Object.keys(Array.prototype).forEach(function(key) { var descriptor = Object.getOwnPropertyDescriptor(Array.prototype, key); if (!descriptor || !descriptor.enumerable || !descriptor.configurable) return; descriptor.enumerable = false; try { Object.defineProperty(Array.prototype, key, descriptor); } catch (error) {} }); } window._barionMakeArrayPrototypeSafe = makeArrayPrototypeSafeForBarion; function bpReady(cb) { if (typeof bp === 'function') { cb(); return; } var attempts = 0; var t = setInterval(function() { attempts++; if (typeof bp === 'function') { clearInterval(t); cb(); } else if (attempts > 50) { clearInterval(t); } }, 100); } window._pendingBarionEvents = window._pendingBarionEvents || []; window.trackBarionEvent = function(eventName, payload) { bpReady(function() { makeArrayPrototypeSafeForBarion(); bp('track', eventName, payload || {}); }); }; while (window._pendingBarionEvents.length) { var pendingBarionEvent = window._pendingBarionEvents.shift(); window.trackBarionEvent(pendingBarionEvent.eventName, pendingBarionEvent.payload); } window._barionGrantConsent = function() { bpReady(function() { bp('consent', 'grantConsent', {}); }); }; if (window._pendingBarionConsent) { window._pendingBarionConsent = false; window._barionGrantConsent(); } window.addEventListener('load', function() { if (typeof getCookie === 'function' && getCookie('cookies_accepted') === 'true') { window._barionGrantConsent(); } }); })(); </script> </body> </html>