{"id":61,"date":"2025-11-06T14:22:15","date_gmt":"2025-11-06T07:22:15","guid":{"rendered":"https:\/\/wucode.net\/staging\/?page_id=61"},"modified":"2026-04-14T14:30:39","modified_gmt":"2026-04-14T07:30:39","slug":"lien-he","status":"publish","type":"page","link":"https:\/\/www.wucode.net\/en\/lien-he\/","title":{"rendered":"Contact"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"61\" class=\"elementor elementor-61\" data-elementor-post-type=\"page\">\n\t\t\t\t<div role=\"main\" class=\"elementor-element elementor-element-bc5ef41 e-con-full e-flex e-con e-parent\" data-id=\"bc5ef41\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0cb9b88 elementor-widget elementor-widget-particle_hero_section\" data-id=\"0cb9b88\" data-element_type=\"widget\" data-widget_type=\"particle_hero_section.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<style>\n\t\t\t#container-ph_canvas_0cb9b88 {\n\t\t\t\tposition: relative;\n\t\t\t\toverflow: hidden;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t}\n\t\t\t#canvas-ph_canvas_0cb9b88 {\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: 0; left: 0; right: 0; bottom: 0;\n\t\t\t\tz-index: 0;\n\t\t\t\tpointer-events: none;\n\t\t\t}\n\t\t\t#container-ph_canvas_0cb9b88 .ph-overlay {\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: 0; left: 0; right: 0; bottom: 0;\n\t\t\t\tz-index: 5;\n\t\t\t\tpointer-events: none;\n\t\t\t}\n\t\t\t#container-ph_canvas_0cb9b88 .ph-content-wrapper {\n\t\t\t\tposition: relative;\n\t\t\t\tz-index: 10;\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\ttext-align: center;\n\t\t\t\tpointer-events: none; \n\t\t\t}\n\t\t\t#container-ph_canvas_0cb9b88 .ph-button {\n\t\t\t\tpointer-events: auto;\n\t\t\t\ttext-decoration: none;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\t\t<\/style>\n\n\t\t<div id=\"container-ph_canvas_0cb9b88\" class=\"ph-container\">\n\t\t\t<canvas id=\"canvas-ph_canvas_0cb9b88\"><\/canvas>\n\t\t\t<div class=\"ph-overlay\"><\/div> <!-- Th\u00eam Background Overlay -->\n\t\t\t\n\t\t\t<div class=\"ph-content-wrapper\" id=\"content-ph_canvas_0cb9b88\">\n\t\t\t\t<div class=\"ph-heading-1\"><\/div>\n\t\t\t\t<div class=\"ph-heading-2\"><\/div>\n\t\t\t\t\n\t\t\t\t<a class=\"ph-button\">\n\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t<\/div>\n\t\t<\/div>\n\n\t\t<script>\n\t\t(function() {\n\t\t\tconst initCanvasWidget = () => {\n\t\t\t\tconst instanceId = 'ph_canvas_0cb9b88';\n\t\t\t\tconst config = {\"shapeType\":\"complex-svg\",\"shapeText\":null,\"shapeFontSize\":1200,\"iconPath\":null,\"iconViewBox\":null,\"svgSource\":\"media\",\"svgUrl\":\"https:\\\/\\\/www.wucode.net\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/Contact-banner-.png\",\"svgInline\":null,\"shapeThickness\":15,\"particleShape\":\"diamond\",\"colors\":{\"base\":\"#000000\",\"accent1\":\"#000000\",\"accent2\":\"#000000\",\"shape\":null},\"triggerMode\":{\"desktop\":\"scroll\",\"tablet\":\"\",\"mobile\":\"\"},\"shapeSize\":{\"desktop\":60,\"tablet\":40,\"mobile\":50},\"totalParticles\":{\"desktop\":3500,\"tablet\":3000,\"mobile\":1500},\"particleSize\":{\"desktop\":2,\"tablet\":1.2,\"mobile\":1},\"animationSpeed\":{\"desktop\":0.1,\"tablet\":\"\",\"mobile\":0.15},\"shapePositionX\":{\"desktop\":0.7,\"tablet\":\"\",\"mobile\":0.7},\"shapePositionY\":{\"desktop\":0.5,\"tablet\":\"\",\"mobile\":0.8}};\n\t\t\t\tconst canvas = document.getElementById('canvas-' + instanceId);\n\t\t\t\tconst container = document.getElementById('container-' + instanceId);\n\t\t\t\t\n\t\t\t\tif (!canvas || !container || container.clientWidth === 0 || container.clientHeight === 0) {\n\t\t\t\t\tsetTimeout(initCanvasWidget, 100);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tconst ctx = canvas.getContext('2d', { willReadFrequently: true });\n\t\t\t\t\n\t\t\t\tlet isHovered = false;\n\t\t\t\tlet animationFrameId;\n\t\t\t\tlet particles = [];\n\t\t\t\tlet targetPoints = [];\n\t\t\t\tlet shapeParticleCount = 0;\n\t\t\t\tlet width = 0;\n\t\t\t\tlet height = 0;\n\t\t\t\tlet hoverTime = 0;\n\t\t\t\tlet isIntersecting = false;\n\t\t\t\tlet isVisible = true; \n\n\t\t\t\tconst getResVal = (valObj, w) => {\n\t\t\t\t\tif (w <= 767 && valObj.mobile !== '') return parseFloat(valObj.mobile);\n\t\t\t\t\tif (w <= 1024 && valObj.tablet !== '') return parseFloat(valObj.tablet);\n\t\t\t\t\treturn parseFloat(valObj.desktop);\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tconst getResString = (valObj, w) => {\n\t\t\t\t\tif (w <= 767 && valObj.mobile !== '') return valObj.mobile;\n\t\t\t\t\tif (w <= 1024 && valObj.tablet !== '') return valObj.tablet;\n\t\t\t\t\treturn valObj.desktop;\n\t\t\t\t};\n\n\t\t\t\tconst handleHoverIn = () => {\n\t\t\t\t\tif (getResString(config.triggerMode, window.innerWidth) === 'hover') isHovered = true;\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tconst handleHoverOut = () => {\n\t\t\t\t\tif (getResString(config.triggerMode, window.innerWidth) === 'hover') isHovered = false;\n\t\t\t\t};\n\n\t\t\t\tcontainer.addEventListener('mouseenter', handleHoverIn);\n\t\t\t\tcontainer.addEventListener('mouseleave', handleHoverOut);\n\t\t\t\tcontainer.addEventListener('touchstart', handleHoverIn, { passive: true });\n\t\t\t\tcontainer.addEventListener('touchend', handleHoverOut);\n\t\t\t\tcontainer.addEventListener('touchcancel', handleHoverOut);\n\n\t\t\t\tconst observer = new IntersectionObserver((entries) => {\n\t\t\t\t\tentries.forEach(entry => {\n\t\t\t\t\t\tisVisible = entry.isIntersecting; \n\t\t\t\t\t\t\n\t\t\t\t\t\tif (entry.intersectionRatio >= 0.4) {\n\t\t\t\t\t\t\tisIntersecting = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tisIntersecting = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (getResString(config.triggerMode, window.innerWidth) === 'scroll') {\n\t\t\t\t\t\t\tisHovered = isIntersecting;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}, { threshold: [0, 0.4] });\n\t\t\t\tobserver.observe(container);\n\n\t\t\t\tconst dpr = window.devicePixelRatio || 1;\n\n\t\t\t\tconst initParticles = async () => {\n\t\t\t\t\twidth = container.clientWidth;\n\t\t\t\t\theight = container.clientHeight;\n\n\t\t\t\t\tif (width <= 0 || height <= 0) return false;\n\n\t\t\t\t\tconst currentTrigger = getResString(config.triggerMode, window.innerWidth);\n\t\t\t\t\tif (currentTrigger === 'scroll') {\n\t\t\t\t\t\tisHovered = isIntersecting;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisHovered = false; \n\t\t\t\t\t}\n\n\t\t\t\t\tconst currentParticlesCount = getResVal(config.totalParticles, window.innerWidth);\n\t\t\t\t\tconst currentPSize = getResVal(config.particleSize, window.innerWidth);\n\t\t\t\t\tconst currentSpeed = getResVal(config.animationSpeed, window.innerWidth);\n\t\t\t\t\tconst currentPosX = getResVal(config.shapePositionX, window.innerWidth);\n\t\t\t\t\tconst currentPosY = getResVal(config.shapePositionY, window.innerWidth);\n\t\t\t\t\tconst currentShapeSize = getResVal(config.shapeSize, window.innerWidth);\n\n\t\t\t\t\tcanvas.width = width * dpr;\n\t\t\t\t\tcanvas.height = height * dpr;\n\t\t\t\t\tcanvas.style.width = width + 'px';\n\t\t\t\t\tcanvas.style.height = height + 'px';\n\t\t\t\t\t\n\t\t\t\t\tctx.setTransform(1, 0, 0, 1, 0, 0);\n\t\t\t\t\tctx.scale(dpr, dpr);\n\n\t\t\t\t\tconst offCanvas = document.createElement('canvas');\n\t\t\t\t\tconst offCtx = offCanvas.getContext('2d', { willReadFrequently: true });\n\t\t\t\t\toffCanvas.width = width;\n\t\t\t\t\toffCanvas.height = height;\n\t\t\t\t\t\n\t\t\t\t\tconst maxAllowedWidth = width * (currentShapeSize \/ 100);\n\t\t\t\t\t\n\t\t\t\t\tif (config.shapeType === 'complex-svg') {\n\t\t\t\t\t\tawait new Promise((resolve) => {\n\t\t\t\t\t\t\tconst img = new Image();\n\t\t\t\t\t\t\timg.crossOrigin = \"Anonymous\"; \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\timg.onload = () => {\n\t\t\t\t\t\t\t\tconst imgAspect = img.width \/ (img.height || 1);\n\t\t\t\t\t\t\t\tlet drawWidth = maxAllowedWidth;\n\t\t\t\t\t\t\t\tlet drawHeight = drawWidth \/ imgAspect;\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tif (drawHeight > height * (currentShapeSize \/ 100)) {\n\t\t\t\t\t\t\t\t\tdrawHeight = height * (currentShapeSize \/ 100);\n\t\t\t\t\t\t\t\t\tdrawWidth = drawHeight * imgAspect;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\toffCtx.drawImage(\n\t\t\t\t\t\t\t\t\timg, \n\t\t\t\t\t\t\t\t\twidth * currentPosX - drawWidth \/ 2, \n\t\t\t\t\t\t\t\t\theight * currentPosY - drawHeight \/ 2, \n\t\t\t\t\t\t\t\t\tdrawWidth, \n\t\t\t\t\t\t\t\t\tdrawHeight\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\timg.onerror = resolve; \n\n\t\t\t\t\t\t\tif (config.svgSource === 'media' && config.svgUrl) {\n\t\t\t\t\t\t\t\timg.src = config.svgUrl;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\timg.src = 'data:image\/svg+xml;charset=utf-8,' + encodeURIComponent(config.svgInline);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t} else if (config.shapeType === 'icon') {\n\t\t\t\t\t\tconst path = new Path2D(config.iconPath);\n\t\t\t\t\t\tconst scale = maxAllowedWidth \/ config.iconViewBox;\n\t\t\t\t\t\t\n\t\t\t\t\t\toffCtx.translate(width * currentPosX, height * currentPosY);\n\t\t\t\t\t\toffCtx.scale(scale, scale);\n\t\t\t\t\t\toffCtx.translate(-config.iconViewBox \/ 2, -config.iconViewBox \/ 2);\n\t\t\t\t\t\t\n\t\t\t\t\t\toffCtx.lineWidth = config.shapeThickness \/ scale; \n\t\t\t\t\t\toffCtx.strokeStyle = 'black';\n\t\t\t\t\t\toffCtx.lineCap = 'round';\n\t\t\t\t\t\toffCtx.lineJoin = 'round';\n\t\t\t\t\t\toffCtx.stroke(path);\n\t\t\t\t\t\t\n\t\t\t\t\t\toffCtx.setTransform(1, 0, 0, 1, 0, 0); \n\t\t\t\t\t} else {\n\t\t\t\t\t\tlet fontSize = config.shapeFontSize;\n\t\t\t\t\t\toffCtx.font = \"bold \" + fontSize + \"px sans-serif\";\n\t\t\t\t\t\t\n\t\t\t\t\t\tlet textWidth = offCtx.measureText(config.shapeText).width;\n\t\t\t\t\t\tif (textWidth > maxAllowedWidth && textWidth > 0) {\n\t\t\t\t\t\t\tfontSize = Math.floor(fontSize * (maxAllowedWidth \/ textWidth));\n\t\t\t\t\t\t\toffCtx.font = \"bold \" + fontSize + \"px sans-serif\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\toffCtx.textAlign = 'center';\n\t\t\t\t\t\toffCtx.textBaseline = 'middle';\n\t\t\t\t\t\toffCtx.lineWidth = config.shapeThickness;\n\t\t\t\t\t\toffCtx.strokeStyle = 'black';\n\t\t\t\t\t\toffCtx.lineCap = 'round';\n\t\t\t\t\t\toffCtx.lineJoin = 'round';\n\t\t\t\t\t\toffCtx.strokeText(config.shapeText, width * currentPosX, height * currentPosY);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst imgData = offCtx.getImageData(0, 0, width, height).data;\n\t\t\t\t\ttargetPoints = [];\n\t\t\t\t\tconst gap = Math.max(Math.floor(width \/ 250), 4); \n\n\t\t\t\t\tfor (let y = 0; y < height; y += gap) {\n\t\t\t\t\t\tfor (let x = 0; x < width; x += gap) {\n\t\t\t\t\t\t\tconst index = (y * width + x) * 4;\n\t\t\t\t\t\t\tconst r = imgData[index];\n\t\t\t\t\t\t\tconst g = imgData[index + 1];\n\t\t\t\t\t\t\tconst b = imgData[index + 2];\n\t\t\t\t\t\t\tconst alpha = imgData[index + 3];\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif (alpha > 50) {\n\t\t\t\t\t\t\t\tconst originalColor = config.shapeType === 'complex-svg' \n\t\t\t\t\t\t\t\t\t? \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (alpha \/ 255) + \")\" \n\t\t\t\t\t\t\t\t\t: config.colors.shape;\n\t\t\t\t\t\t\t\ttargetPoints.push({ x: x, y: y, color: originalColor });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (targetPoints.length > currentParticlesCount * 0.85) {\n\t\t\t\t\t\ttargetPoints.sort(() => Math.random() - 0.5);\n\t\t\t\t\t\ttargetPoints = targetPoints.slice(0, Math.floor(currentParticlesCount * 0.85));\n\t\t\t\t\t}\n\n\t\t\t\t\tparticles = [];\n\t\t\t\t\tshapeParticleCount = targetPoints.length;\n\n\t\t\t\t\tfor (let i = 0; i < currentParticlesCount; i++) {\n\t\t\t\t\t\tconst isShapeParticle = i < shapeParticleCount;\n\t\t\t\t\t\tconst target = isShapeParticle ? targetPoints[i] : null;\n\n\t\t\t\t\t\tlet particleType = 'bg-float';\n\t\t\t\t\t\tif (isShapeParticle) {\n\t\t\t\t\t\t\tparticleType = 'shape';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tparticleType = Math.random() < 0.25 ? 'bg-suck' : 'bg-float';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst randomShapeTarget = shapeParticleCount > 0 \n\t\t\t\t\t\t\t? targetPoints[Math.floor(Math.random() * shapeParticleCount)] \n\t\t\t\t\t\t\t: { x: width * currentPosX, y: height * currentPosY };\n\n\t\t\t\t\t\tlet hoverColor = config.colors.base;\n\t\t\t\t\t\tif (isShapeParticle) {\n\t\t\t\t\t\t\thoverColor = target.color; \n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst rand = Math.random();\n\t\t\t\t\t\t\tif (rand > 0.98) hoverColor = config.colors.accent1;\n\t\t\t\t\t\t\telse if (rand > 0.8) hoverColor = config.colors.accent2;\n\t\t\t\t\t\t\telse hoverColor = config.colors.base;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tparticles.push({\n\t\t\t\t\t\t\tx: Math.random() * width,\n\t\t\t\t\t\t\ty: Math.random() * height,\n\t\t\t\t\t\t\toriginX: Math.random() * width,\n\t\t\t\t\t\t\toriginY: Math.random() * height,\n\t\t\t\t\t\t\ttargetX: target ? target.x : Math.random() * width,\n\t\t\t\t\t\t\ttargetY: target ? target.y : Math.random() * height,\n\t\t\t\t\t\t\tmagnetX: randomShapeTarget.x,\n\t\t\t\t\t\t\tmagnetY: randomShapeTarget.y,\n\t\t\t\t\t\t\ttype: particleType,\n\t\t\t\t\t\t\tsize: Math.random() * (currentPSize * 0.8) + (currentPSize * 0.4),\n\t\t\t\t\t\t\tcolorHover: hoverColor,\n\t\t\t\t\t\t\tvx: (Math.random() - 0.5) * 0.3,\n\t\t\t\t\t\t\tvy: (Math.random() - 0.5) * 0.3,\n\t\t\t\t\t\t\tconfigSpeed: currentSpeed\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tparticles.sort((a, b) => a.colorHover.localeCompare(b.colorHover));\n\t\t\t\t\t\n\t\t\t\t\treturn true;\n\t\t\t\t};\n\n\t\t\t\tconst draw = () => {\n\t\t\t\t\tif (!document.body.contains(canvas)) {\n\t\t\t\t\t\tif (animationFrameId) cancelAnimationFrame(animationFrameId);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationFrameId = requestAnimationFrame(draw);\n\n\t\t\t\t\tif (!isVisible) return; \n\n\t\t\t\t\tif (width > 0 && height > 0) {\n\t\t\t\t\t\tctx.clearRect(0, 0, width, height);\n\n\t\t\t\t\t\tif (isHovered) hoverTime++; else hoverTime = 0;\n\n\t\t\t\t\t\tlet lastColor = null;\n\t\t\t\t\t\tctx.beginPath(); \n\n\t\t\t\t\t\tparticles.forEach(p => {\n\t\t\t\t\t\t\tlet tx, ty;\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif (isHovered) {\n\t\t\t\t\t\t\t\tif (p.type === 'shape') {\n\t\t\t\t\t\t\t\t\ttx = p.targetX; ty = p.targetY;\n\t\t\t\t\t\t\t\t\tp.x += (tx - p.x) * p.configSpeed;\n\t\t\t\t\t\t\t\t\tp.y += (ty - p.y) * p.configSpeed;\n\t\t\t\t\t\t\t\t} else if (p.type === 'bg-suck' && hoverTime > 40) {\n\t\t\t\t\t\t\t\t\tconst dx = p.magnetX - p.originX;\n\t\t\t\t\t\t\t\t\tconst dy = p.magnetY - p.originY;\n\t\t\t\t\t\t\t\t\tconst dist = Math.sqrt(dx * dx + dy * dy);\n\n\t\t\t\t\t\t\t\t\tif (dist < 20) {\n\t\t\t\t\t\t\t\t\t\tconst angle = Math.random() * Math.PI * 2;\n\t\t\t\t\t\t\t\t\t\tconst radius = Math.max(width, height) * 0.6; \n\t\t\t\t\t\t\t\t\t\tp.originX = width \/ 2 + Math.cos(angle) * radius;\n\t\t\t\t\t\t\t\t\t\tp.originY = height \/ 2 + Math.sin(angle) * radius;\n\t\t\t\t\t\t\t\t\t\tp.x = p.originX; p.y = p.originY;\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\tconst newTarget = shapeParticleCount > 0 \n\t\t\t\t\t\t\t\t\t\t\t? targetPoints[Math.floor(Math.random() * shapeParticleCount)] \n\t\t\t\t\t\t\t\t\t\t\t: { x: width \/ 2, y: height \/ 2 };\n\t\t\t\t\t\t\t\t\t\tp.magnetX = newTarget.x;\n\t\t\t\t\t\t\t\t\t\tp.magnetY = newTarget.y;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tp.originX += dx * 0.01; \n\t\t\t\t\t\t\t\t\t\tp.originY += dy * 0.01;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttx = p.originX; ty = p.originY;\n\t\t\t\t\t\t\t\t\tp.x += (tx - p.x) * p.configSpeed;\n\t\t\t\t\t\t\t\t\tp.y += (ty - p.y) * p.configSpeed;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tp.originX += p.vx; p.originY += p.vy;\n\t\t\t\t\t\t\t\t\tif (p.originX < 0 || p.originX > width) p.vx *= -1;\n\t\t\t\t\t\t\t\t\tif (p.originY < 0 || p.originY > height) p.vy *= -1;\n\t\t\t\t\t\t\t\t\ttx = p.originX; ty = p.originY;\n\t\t\t\t\t\t\t\t\tp.x += (tx - p.x) * p.configSpeed;\n\t\t\t\t\t\t\t\t\tp.y += (ty - p.y) * p.configSpeed;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tp.originX += p.vx; p.originY += p.vy;\n\t\t\t\t\t\t\t\tif (p.originX < 0 || p.originX > width) p.vx *= -1;\n\t\t\t\t\t\t\t\tif (p.originY < 0 || p.originY > height) p.vy *= -1;\n\t\t\t\t\t\t\t\ttx = p.originX; ty = p.originY;\n\t\t\t\t\t\t\t\tp.x += (tx - p.x) * p.configSpeed;\n\t\t\t\t\t\t\t\tp.y += (ty - p.y) * p.configSpeed;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlet currentColor = isHovered ? p.colorHover : config.colors.base;\n\n\t\t\t\t\t\t\tif (currentColor !== lastColor) {\n\t\t\t\t\t\t\t\tif (lastColor !== null) ctx.fill(); \n\t\t\t\t\t\t\t\tctx.fillStyle = currentColor;\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tlastColor = currentColor;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\/\/ Thu\u1eadt to\u00e1n v\u1ebd h\u00ecnh d\u1ea1ng (Shape Generator)\n\t\t\t\t\t\t\tif (config.particleShape === 'square') {\n\t\t\t\t\t\t\t\tctx.rect(p.x - p.size, p.y - p.size, p.size * 2, p.size * 2);\n\t\t\t\t\t\t\t} else if (config.particleShape === 'triangle') {\n\t\t\t\t\t\t\t\tctx.moveTo(p.x, p.y - p.size);\n\t\t\t\t\t\t\t\tctx.lineTo(p.x + p.size, p.y + p.size);\n\t\t\t\t\t\t\t\tctx.lineTo(p.x - p.size, p.y + p.size);\n\t\t\t\t\t\t\t\tctx.lineTo(p.x, p.y - p.size);\n\t\t\t\t\t\t\t} else if (config.particleShape === 'diamond') {\n\t\t\t\t\t\t\t\tctx.moveTo(p.x, p.y - p.size);\n\t\t\t\t\t\t\t\tctx.lineTo(p.x + p.size, p.y);\n\t\t\t\t\t\t\t\tctx.lineTo(p.x, p.y + p.size);\n\t\t\t\t\t\t\t\tctx.lineTo(p.x - p.size, p.y);\n\t\t\t\t\t\t\t\tctx.lineTo(p.x, p.y - p.size);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\/\/ Default l\u00e0 Circle (H\u00ecnh tr\u00f2n)\n\t\t\t\t\t\t\t\tctx.moveTo(p.x + p.size, p.y);\n\t\t\t\t\t\t\t\tctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (lastColor !== null) ctx.fill(); \n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tconst run = async () => {\n\t\t\t\t\tif (document.fonts) {\n\t\t\t\t\t\tawait document.fonts.ready;\n\t\t\t\t\t}\n\t\t\t\t\tawait initParticles();\n\t\t\t\t\tdraw();\n\t\t\t\t};\n\n\t\t\t\trun();\n\n\t\t\t\tlet resizeTimeout;\n\t\t\t\tconst resizeObserver = new ResizeObserver((entries) => {\n\t\t\t\t\tfor (let entry of entries) {\n\t\t\t\t\t\tclearTimeout(resizeTimeout);\n\t\t\t\t\t\tresizeTimeout = setTimeout(async () => {\n\t\t\t\t\t\t\tawait initParticles();\n\t\t\t\t\t\t}, 150);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tresizeObserver.observe(container);\n\t\t\t};\n\n\t\t\tif (document.readyState === 'loading') {\n\t\t\t\tdocument.addEventListener('DOMContentLoaded', initCanvasWidget);\n\t\t\t} else {\n\t\t\t\tsetTimeout(initCanvasWidget, 50);\n\t\t\t}\n\t\t})();\n\t\t<\/script>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div role=\"main\" class=\"elementor-element elementor-element-2387439 e-flex e-con-boxed e-con e-child\" data-id=\"2387439\" data-element_type=\"container\" data-settings=\"{&quot;position&quot;:&quot;absolute&quot;,&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c477699 elementor-widget elementor-widget-heading\" data-id=\"c477699\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">H\u1ee3p t\u00e1c c\u00f9ng nhau<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6d83a25 elementor-widget__width-initial elementor-widget-mobile__width-inherit elementor-widget elementor-widget-heading\" data-id=\"6d83a25\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Li\u00ean h\u1ec7 Wucode \u0111\u1ec3 \u0111\u01b0\u1ee3c t\u01b0 v\u1ea5n thi\u1ebft k\u1ebf Website , App Mobile v\u00e0 c\u00e1c gi\u1ea3i ph\u00e1p c\u00f4ng ngh\u1ec7. Ch\u00fang t\u00f4i cam k\u1ebft \u0111\u1ed3ng h\u00e0nh c\u00f9ng doanh nghi\u1ec7p b\u1ea1n.<\/h2>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div role=\"main\" class=\"elementor-element elementor-element-fa1a3d5 e-flex e-con-boxed e-con e-parent\" data-id=\"fa1a3d5\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div role=\"main\" class=\"elementor-element elementor-element-50a8cda e-con-full e-flex e-con e-child\" data-id=\"50a8cda\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6c9a56d elementor-widget elementor-widget-heading\" data-id=\"6c9a56d\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\"><span>\/\/<\/span>Contact Us<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-16d2b81 elementor-widget elementor-widget-shortcode\" data-id=\"16d2b81\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\n<div class=\"wpcf7 no-js\" id=\"wpcf7-f1519-o1\" lang=\"en-US\" dir=\"ltr\" data-wpcf7-id=\"1519\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/en\/wp-json\/wp\/v2\/pages\/61#wpcf7-f1519-o1\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Contact form\" novalidate=\"novalidate\" data-status=\"init\" data-trp-original-action=\"\/en\/wp-json\/wp\/v2\/pages\/61#wpcf7-f1519-o1\">\n<fieldset class=\"hidden-fields-container\"><input type=\"hidden\" name=\"_wpcf7\" value=\"1519\" \/><input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.1.3\" \/><input type=\"hidden\" name=\"_wpcf7_locale\" value=\"en_US\" \/><input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f1519-o1\" \/><input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/><input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/>\n<\/fieldset>\n<div class=\"container two-column\">\n\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"your-name\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Full Name\" value=\"\" type=\"text\" name=\"your-name\" \/><\/span><span class=\"wpcf7-form-control-wrap\" data-name=\"your-company\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Company Name\" value=\"\" type=\"text\" name=\"your-company\" \/><\/span>\n\t<\/p>\n<\/div>\n<div class=\"container two-column\">\n\t<div class=\"phone-container\">\n\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"your-email\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Email Address\" value=\"\" type=\"email\" name=\"your-email\" \/><\/span><span class=\"phone-wrap\"><span class=\"wpcf7-form-control-wrap\" data-name=\"phone-prefix\"><input size=\"40\" class=\"wpcf7-form-control wpcf7-phonetext wpcf7-text wpcf7-validates-as-phonetext\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"phone-prefix\" \/><input type=\"hidden\" name=\"phone-prefix-country-code\" class=\"wpcf7-phonetext-country-code\" \/><\/span><span class=\"wpcf7-form-control-wrap\" data-name=\"your-phone\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-tel wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-tel\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Phone Number\" value=\"\" type=\"tel\" name=\"your-phone\" \/><\/span><\/span>\n\t\t<\/p>\n\t<\/div>\n<\/div>\n<div class=\"container\">\n\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"your-message\"><textarea cols=\"40\" rows=\"10\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea\" aria-invalid=\"false\" placeholder=\"Message\" name=\"your-message\"><\/textarea><\/span>\n\t<\/p>\n<\/div>\n<div class=\"container\">\n\t<p><label>What is the allocated budget for this project?<\/label><span class=\"wpcf7-form-control-wrap\" data-name=\"your-budgeted\"><select class=\"wpcf7-form-control wpcf7-select\" aria-invalid=\"false\" name=\"your-budgeted\"><option value=\"\">Not Sure<\/option><option value=\"D\u01b0\u1edbi $10k\">Under $10k<\/option><option value=\"$10k - $20k\">$10k - $20k<\/option><option value=\"$20k - $50k\">$20k - $50k<\/option><option value=\"$50k - $100k\">$50k - $100k<\/option><option value=\"$100k+\">$100k+<\/option><\/select><\/span>\n\t<\/p>\n<\/div>\n<div class=\"container\">\n\t<p><label>How did you hear about us?<\/label><span class=\"wpcf7-form-control-wrap\" data-name=\"your-reason\"><select class=\"wpcf7-form-control wpcf7-select\" aria-invalid=\"false\" name=\"your-reason\"><option value=\"\">Web Search \/ Google<\/option><option value=\"\u0110\u00e3 t\u1eebng thu\u00ea Multidots cho WordCamp ho\u1eb7c c\u00e1c s\u1ef1 ki\u1ec7n kh\u00e1c tr\u01b0\u1edbc \u0111\u00e2y\">WordCamp Or Other Event Hired Multidots In The Past<\/option><option value=\"\u0110\u00e3 l\u00e0 kh\u00e1ch h\u00e0ng c\u1ee7a Multidots\">Already A Client Of Multidots<\/option><option value=\"\u0110\u01b0\u1ee3c gi\u1edbi thi\u1ec7u b\u1edfi b\u1ea1n b\u00e8\">Referred By A Friend<\/option><option value=\"\u0110\u01b0\u1ee3c gi\u1edbi thi\u1ec7u b\u1edfi kh\u00e1ch h\u00e0ng c\u1ee7a Multidots\">Referred By A Client Of Multidots<\/option><option value=\"WordPress VIP\">WordPress VIP<\/option><option value=\"Clutch\">Clutch<\/option><option value=\"M\u1ea1ng x\u00e3 h\u1ed9i\">Social Media<\/option><option value=\"Kh\u00e1c\">Other<\/option><\/select><\/span>\n\t<\/p>\n<\/div>\n<div class=\"container\">\n\t<p><label>Please provide more information or your ideas<\/label><span class=\"wpcf7-form-control-wrap\" data-name=\"files-upload\"><input size=\"40\" class=\"wpcf7-form-control wpcf7-drag-n-drop-file d-none\" aria-invalid=\"false\" type=\"file\" multiple=\"multiple\" data-name=\"files-upload\" data-type=\"jpg|jpeg|png|gif|pdf|doc|docx|xls|xlsx|ppt|pptx|odt|txt|rtf|zip|rar|7z|mp3|wav|mp4|mov|wmv|avi|ai|psd|eps|svg\" data-limit=\"67108864\" data-min=\"1\" data-max=\"50\" data-id=\"1519\" data-version=\"free version 1.3.9.6\" accept=\".jpg, .jpeg, .png, .gif, .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .odt, .txt, .rtf, .zip, .rar, .7z, .mp3, .wav, .mp4, .mov, .wmv, .avi, .ai, .psd, .eps, .svg\" \/><\/span>\n\t<\/p>\n<\/div>\n<p><input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"Send\" \/>\n<\/p><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<input type=\"hidden\" name=\"trp-form-language\" value=\"en\"\/><\/form>\n<\/div>\n<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e722d42 elementor-widget elementor-widget-heading\" data-id=\"e722d42\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<div class=\"elementor-heading-title elementor-size-default translation-block\">By submitting this form, you agree to our <a href=\"https:\/\/www.wucode.net\/en\/chinh-sach-bao-mat\/\" target=\"_blank\">Privacy Policy<\/a><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div role=\"main\" class=\"elementor-element elementor-element-68a980a e-con-full e-flex e-con e-child\" data-id=\"68a980a\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-249578f elementor-blockquote--skin-quotation elementor-blockquote--align-left elementor-blockquote--button-color-official elementor-widget elementor-widget-blockquote\" data-id=\"249578f\" data-element_type=\"widget\" data-widget_type=\"blockquote.default\">\n\t\t\t\t\t\t\t<blockquote class=\"elementor-blockquote\">\n\t\t\t<p class=\"elementor-blockquote__content\">\n\t\t\t\tWhen the team proposed migrating 11 websites in just 12 weeks, I was highly skeptical and wasn\u2019t sure it was even feasible! But they delivered. It\u2019s been a total pleasure working with the entire team.\t\t\t<\/p>\n\t\t\t\t\t\t\t<div class=\"e-q-footer\">\n\t\t\t\t\t\t\t\t\t\t\t<cite class=\"elementor-blockquote__author\">Chris<small>CEO<\/small><\/cite>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/blockquote>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>H\u1ee3p t\u00e1c c\u00f9ng nhau Li\u00ean h\u1ec7 Wucode \u0111\u1ec3 \u0111\u01b0\u1ee3c t\u01b0 v\u1ea5n thi\u1ebft k\u1ebf Website , App Mobile v\u00e0 c\u00e1c gi\u1ea3i ph\u00e1p c\u00f4ng ngh\u1ec7. Ch\u00fang t\u00f4i cam k\u1ebft \u0111\u1ed3ng h\u00e0nh c\u00f9ng doanh nghi\u1ec7p b\u1ea1n. \/\/Li\u00ean h\u1ec7 B\u1eb1ng c\u00e1ch g\u1eedi bi\u1ec3u m\u1eabu n\u00e0y, b\u1ea1n \u0111\u1ed3ng \u00fd v\u1edbi ch\u00ednh s\u00e1ch b\u1ea3o m\u1eadt c\u1ee7a ch\u00fang t\u00f4i Khi \u0111\u1ed1i t\u00e1c [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-61","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/pages\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":349,"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/pages\/61\/revisions"}],"predecessor-version":[{"id":4135,"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/pages\/61\/revisions\/4135"}],"wp:attachment":[{"href":"https:\/\/www.wucode.net\/en\/wp-json\/wp\/v2\/media?parent=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}