End to End Engineering Precision

One Integrated Partner
DRS Engineering

01.
Engineering Consultancy
02.
Process & Layout Design
03.
Automation & Optimisation
04.
Installation & Commissioning Support
DRS Engineering

01.
Advisory and Consultancy
02.
Process & Layout Design
03.
Automation & Optimisation
04.
Installation & Commissioning Support
DRS Industrial Supply

01.
Mechanical, Electrical & Automation Supply
02.
Custom Fabrication & Structural
03.
Technical Sourcing & Quality Assurance
04.
Responsive Single-Source Partner
01.
Mechanical Components
• Bearings and housings
• Gearboxes and drives
• Hydraulic and pneumatic components
• Shafts, rollers and assemblies
• Custom machined parts
02.
Electrical Components
• Motors and VFDs
• MCCs and switchgear
• Cables, trays and terminations
• Instrumentation and sensors
• Control panels
03.
Automation & Controls
• PLC CPUs and power supplies
• HMIs and networking components
• Field sensors and I/O devices
• Panel wiring and integration
04.
Fabrication & Structural
• Steel frames and platforms
• Custom brackets and supports
• Equipment bases and skids
• Refurbishment and re-engineering

DRS SiteCORE

01.
Modular Infrastructure
02.
Tool Management Systems
03.
Digital Inventory Control
04.
Mobilisation & Site Support
Trusted by Customers
Based in the UAE. Operating Internationally.
Based in the UAE. Operating Internationally.
Based in the UAE. Operating Internationally.
Based in the UAE.
Operating Internationally.
.drs-map{
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
/* slides */
.drs-map .drs-map-slide{
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: block;
opacity: 0;
transition: opacity calc(var(--drs-fade-ms, 700) * 1ms) ease;
will-change: opacity;
}
.drs-map .drs-map-slide.is-active{
opacity: 1;
}
/* land */
.drs-map .drs-land path{
fill: #1a2325;
stroke: rgba(255,255,255,0.10);
stroke-width: 0.6;
vector-effect: non-scaling-stroke;
}
/* land texture overlay */
.drs-map .drs-land-texture{
mix-blend-mode: overlay;
pointer-events: none;
}
/* highlights */
.drs-map .drs-hi-outline path{
fill: none;
stroke: #E9F8F6;
stroke-width: 2;
vector-effect: non-scaling-stroke;
stroke-opacity: 0.9;
}
.drs-map .drs-hi-pulse path{
fill: none;
stroke: #E9F8F6;
stroke-width: 7;
vector-effect: non-scaling-stroke;
opacity: 0.10;
}
/* ===== Region name overlay (LIST) ===== */
.drs-map .drs-region-labels{
position: absolute;
top: 40px;
right: 40px;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: var(--drs-label-gap, 8px);
background: transparent;
border: none;
padding: 0;
margin: 0;
pointer-events: none;
}
.drs-map .drs-region-label{
display: inline-flex;
flex-direction: column;
align-items: flex-end; /* keeps underline aligned to right */
gap: 4px;
font-family: Aeonik, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
font-size: calc(clamp(16px, 1.05vw, 18px) * var(--drs-label-font-scale, 1));
font-weight: 400;
line-height: 1.35em;
color: rgba(233, 248, 246, 0.96);
opacity: var(--drs-label-opacity-inactive, 0.4);
transition: opacity 0.4s ease;
white-space: nowrap;
}
/* wrap text so underline can match text width */
.drs-map .drs-region-label .drs-region-label-text{
display: inline-block; /* shrink-to-text */
}
.drs-map .drs-region-label.is-active{
opacity: 1;
}
/* underline - width matches text */
.drs-map .drs-region-label .drs-underline{
width: 100%;
height: 1.5px;
border-radius: 4px;
background: rgba(233, 248, 246, 0.96);
transform-origin: right center;
transform: scaleX(0);
transition-property: transform;
transition-timing-function: linear;
transition-duration: calc(var(--drs-underline-out-ms, 400) * 1ms);
}
/* IN (long) when active */
.drs-map .drs-region-label.is-active .drs-underline{
transform: scaleX(1);
transition-duration: calc(var(--drs-underline-in-ms, 5000) * 1ms);
}
/* =========================
MOBILE: show ONLY active label + vertically center the container on right
========================= */
@media (max-width: 767px){
.drs-map{
--drs-label-gap: 0px; /* irrelevant since only one item shows */
--drs-label-font-scale: 0.80; /* overall scale */
}
.drs-map .drs-region-labels{
top: 50%;
right: 20px;
left: auto;
bottom: auto;
transform: translateY(-50%);
display: block; /* no flex stacking on mobile */
text-align: right;
max-width: calc(100% - 40px);
}
/* hide all by default */
.drs-map .drs-region-label{
display: none;
opacity: 1; /* not used on mobile */
transition: none;
}
/* show only active */
.drs-map .drs-region-label.is-active{
display: inline-flex;
align-items: flex-end;
gap: 3px;
font-size: calc(clamp(13px, 3.4vw, 15px) * var(--drs-label-font-scale, 1));
line-height: 1.2em;
}
.drs-map .drs-region-label .drs-underline{
height: 1px;
}
}<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script>
<script>
/* =========================
DRS MAP SLIDES (RESPONSIVE)
Update:
- Mobile: only ACTIVE region name is shown; container is vertically centered on right
- Removes Western Europe overseas outliers (e.g., French Guiana showing with France)
- Underline OUT is fast (0.4s) when switching labels
========================= */
/* ===== TUNABLE ===== */
const DRS_SLIDES_CFG = {
topojsonUrl: "https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json",
slideDurationMs: 5000,
fadeMs: 700,
// ZOOM CONTROL
zoomFactor: 2.0,
// PAN ONLY
panToCenter: true,
panEdgePaddingPx: 60,
regionCenterNudge: { x: 0, y: 0 },
// palette / look
ocean1: "#05090d",
ocean2: "#020406",
ocean3: "#0a1016",
land: "#1a2325",
border: "rgba(255,255,255,0.10)",
borderWidth: 0.6,
hiColor: "#E9F8F6",
hiDotOpacity: 0.62,
hiOutlineWidth: 2.0,
dotRadius: 1.35,
dotGap: 6,
glowOn: true,
glowBlur: 6,
glowOpacity: 0.55,
// STATIC textures (not animated)
landTextureOn: true,
landTextureOpacity: 0.20,
oceanVignetteOn: true,
oceanLightSweepOn: true,
filmGrainOn: true,
filmGrainOpacity: 0.10,
// OFF (laggy)
animationsOn: false,
// REGION ORDER (slides)
regionOrder: ["gulf","usa","western_europe","india","indonesia","australia"],
/* ===== LABEL LIST UI ===== */
labels: {
gapPx: 8,
inactiveOpacity: 0.4,
underlineOutMs: 400
},
// responsive safety
minW: 320,
minH: 240,
resizeDebounceMs: 150,
// Outlier removal (for overseas polygons attached to EU countries)
outlierTrim: {
enabled: true,
maxDistFactor: 0.55 // * min(W,H)
}
};
/* ===== REGIONS ===== */
const DRS_REGIONS = [
{
key: "western_europe",
label: "Western Europe",
countries: [
"United Kingdom","Ireland","France","Belgium","Netherlands","Luxembourg",
"Germany","Switzerland","Austria","Spain","Portugal","Italy"
]
},
{
key: "gulf",
label: "Gulf Region",
countries: ["United Arab Emirates","Saudi Arabia","Qatar","Oman","Kuwait","Bahrain"]
},
{ key: "india", label: "India", countries: ["India"] },
{ key: "indonesia", label: "Indonesia", countries: ["Indonesia"] },
{ key: "australia", label: "Australia", countries: ["Australia"] },
{ key: "usa", label: "USA", countries: ["United States of America"] }
];
const NAME_ALIASES = {
"united states": "united states of america",
"usa": "united states of america",
"u.s.a.": "united states of america",
"u.s.": "united states of america",
"uk": "united kingdom",
"u.k.": "united kingdom",
"united kingdom of great britain and northern ireland": "united kingdom"
};
/* =========================
HELPERS
========================= */
const norm = (s) =>
String(s || "")
.trim()
.toLowerCase()
.replace(/\s+/g, " ")
.replace(/[’']/g, "'");
const canonicalize = (name) => {
const n = norm(name);
return NAME_ALIASES[n] ? NAME_ALIASES[n] : n;
};
function clearContainer(el){
while (el.firstChild) el.removeChild(el.firstChild);
}
function buildCountryToRegionMap(){
const m = new Map();
DRS_REGIONS.forEach(r => r.countries.forEach(c => m.set(canonicalize(c), r.key)));
return m;
}
function getRegion(key){
return DRS_REGIONS.find(r => r.key === key);
}
function clamp(v, min, max){
return Math.max(min, Math.min(max, v));
}
function getContainerSize(el){
const r = el.getBoundingClientRect();
const W = Math.max(DRS_SLIDES_CFG.minW, Math.round(r.width || 0));
const H = Math.max(DRS_SLIDES_CFG.minH, Math.round(r.height || 0));
return { W, H };
}
function median(arr){
if (!arr || !arr.length) return 0;
const a = arr.slice().sort((x,y) => x-y);
const m = Math.floor(a.length/2);
return a.length % 2 ? a[m] : (a[m-1] + a[m]) / 2;
}
function splitToPolygons(geom){
if (!geom) return [];
if (geom.type === "Polygon") return [geom.coordinates];
if (geom.type === "MultiPolygon") return geom.coordinates.slice();
return [];
}
function featureFromPolygonCoords(baseFeature, polyCoords){
return {
type: "Feature",
properties: baseFeature.properties,
id: baseFeature.id,
geometry: { type: "Polygon", coordinates: polyCoords }
};
}
/* =========================
TOPO CACHE
========================= */
let _DRS_TOPO_CACHE = null;
async function loadWorld(){
if (_DRS_TOPO_CACHE) return _DRS_TOPO_CACHE;
const topo = await fetch(DRS_SLIDES_CFG.topojsonUrl).then(r => r.json());
const countriesObj = topo.objects && (topo.objects.countries || topo.objects.ne_110m_admin_0_countries);
if (!countriesObj) throw new Error("TopoJSON object 'countries' not found.");
const fc = topojson.feature(topo, countriesObj);
_DRS_TOPO_CACHE = { fc, features: fc.features || [] };
return _DRS_TOPO_CACHE;
}
/* =========================
OUTLIER TRIM (fixes French Guiana etc.)
========================= */
function trimOutlierPolygons(regionKey, regionFeats, projection, W, H){
if (!DRS_SLIDES_CFG.outlierTrim?.enabled) return regionFeats;
if (!regionFeats || !regionFeats.length) return regionFeats;
if (regionKey !== "western_europe") return regionFeats;
const polys = [];
const centers = [];
for (const f of regionFeats){
const polyList = splitToPolygons(f.geometry);
for (const polyCoords of polyList){
const pf = featureFromPolygonCoords(f, polyCoords);
const cLonLat = d3.geoCentroid(pf);
const p = projection(cLonLat);
if (!p) continue;
polys.push(pf);
centers.push({ x: p[0], y: p[1] });
}
}
if (polys.length <= 1) return regionFeats;
const mx = median(centers.map(d => d.x));
const my = median(centers.map(d => d.y));
const maxDist = (Math.min(W, H) * (DRS_SLIDES_CFG.outlierTrim.maxDistFactor ?? 0.55));
const maxDist2 = maxDist * maxDist;
const kept = [];
for (let i = 0; i < polys.length; i++){
const dx = centers[i].x - mx;
const dy = centers[i].y - my;
const d2 = dx*dx + dy*dy;
if (d2 <= maxDist2) kept.push(polys[i]);
}
return kept.length ? kept : regionFeats;
}
/* =========================
BUILD ONE SLIDE SVG (responsive size)
========================= */
async function buildMapSlideSVG({ regionKey, uid, W, H }){
const { fc: worldFC, features } = await loadWorld();
const countryToRegion = buildCountryToRegionMap();
const neededCountries = new Set([...countryToRegion.keys()]);
const regionBuckets = new Map(DRS_REGIONS.map(r => [r.key, []]));
for (const f of features){
const ck = canonicalize(f?.properties?.name);
if (neededCountries.has(ck)){
const rk = countryToRegion.get(ck);
if (regionBuckets.has(rk)) regionBuckets.get(rk).push(f);
}
}
let regionFeats = regionBuckets.get(regionKey) || [];
const OCEAN_ID = `drsOcean-${uid}`;
const DOTS_ID = `drsDots-${uid}`;
const GLOW_ID = `drsGlow-${uid}`;
const VIGNETTE_ID = `drsVignette-${uid}`;
const SWEEP_ID = `drsSweep-${uid}`;
const LANDTEX_ID = `drsLandTex-${uid}`;
const GRAIN_ID = `drsGrain-${uid}`;
const svg = d3.create("svg")
.attr("class", "drs-map-slide")
.attr("viewBox", `0 0 ${W} ${H}`)
.attr("preserveAspectRatio", "xMidYMid slice");
const defs = svg.append("defs");
const oceanGrad = defs.append("radialGradient")
.attr("id", OCEAN_ID)
.attr("cx", "50%").attr("cy", "40%").attr("r", "95%");
oceanGrad.append("stop").attr("offset", "0%").attr("stop-color", DRS_SLIDES_CFG.ocean3);
oceanGrad.append("stop").attr("offset", "55%").attr("stop-color", DRS_SLIDES_CFG.ocean1);
oceanGrad.append("stop").attr("offset", "100%").attr("stop-color", DRS_SLIDES_CFG.ocean2);
const vignette = defs.append("radialGradient")
.attr("id", VIGNETTE_ID)
.attr("cx", "50%").attr("cy", "50%").attr("r", "75%");
vignette.append("stop").attr("offset", "0%").attr("stop-color", "rgba(0,0,0,0)");
vignette.append("stop").attr("offset", "62%").attr("stop-color", "rgba(0,0,0,0.18)");
vignette.append("stop").attr("offset", "100%").attr("stop-color", "rgba(0,0,0,0.62)");
const sweep = defs.append("linearGradient")
.attr("id", SWEEP_ID)
.attr("x1", "0%").attr("y1", "0%")
.attr("x2", "100%").attr("y2", "100%");
sweep.append("stop").attr("offset", "0%").attr("stop-color", "rgba(255,255,255,0)");
sweep.append("stop").attr("offset", "46%").attr("stop-color", "rgba(255,255,255,0.06)");
sweep.append("stop").attr("offset", "54%").attr("stop-color", "rgba(255,255,255,0.0)");
sweep.append("stop").attr("offset", "100%").attr("stop-color", "rgba(255,255,255,0)");
const grain = defs.append("filter")
.attr("id", GRAIN_ID)
.attr("x", "-10%").attr("y", "-10%")
.attr("width", "120%").attr("height", "120%");
grain.append("feTurbulence")
.attr("type", "fractalNoise")
.attr("baseFrequency", "0.9")
.attr("numOctaves", "2")
.attr("seed", "3")
.attr("result", "noise");
grain.append("feColorMatrix")
.attr("in", "noise")
.attr("type", "matrix")
.attr("values", `
0 0 0 0 0.6
0 0 0 0 0.6
0 0 0 0 0.6
0 0 0 0.7 0
`.trim());
const pattern = defs.append("pattern")
.attr("id", DOTS_ID)
.attr("patternUnits", "userSpaceOnUse")
.attr("width", DRS_SLIDES_CFG.dotGap)
.attr("height", DRS_SLIDES_CFG.dotGap);
pattern.append("circle")
.attr("cx", DRS_SLIDES_CFG.dotGap / 2)
.attr("cy", DRS_SLIDES_CFG.dotGap / 2)
.attr("r", DRS_SLIDES_CFG.dotRadius)
.attr("fill", DRS_SLIDES_CFG.hiColor)
.attr("opacity", 1);
const glow = defs.append("filter")
.attr("id", GLOW_ID)
.attr("x", "-30%").attr("y", "-30%")
.attr("width", "160%").attr("height", "160%");
glow.append("feGaussianBlur")
.attr("in", "SourceGraphic")
.attr("stdDeviation", DRS_SLIDES_CFG.glowBlur)
.attr("result", "blur");
glow.append("feColorMatrix")
.attr("in", "blur")
.attr("type", "matrix")
.attr("values", `
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 ${DRS_SLIDES_CFG.glowOpacity} 0
`.trim())
.attr("result", "glowAlpha");
const gm = glow.append("feMerge");
gm.append("feMergeNode").attr("in", "glowAlpha");
gm.append("feMergeNode").attr("in", "SourceGraphic");
const landTex = defs.append("filter")
.attr("id", LANDTEX_ID)
.attr("x", "-10%").attr("y", "-10%")
.attr("width", "120%").attr("height", "120%");
landTex.append("feTurbulence")
.attr("type", "fractalNoise")
.attr("baseFrequency", "0.85")
.attr("numOctaves", "2")
.attr("seed", "9")
.attr("result", "turb");
svg.append("rect")
.attr("x", 0).attr("y", 0)
.attr("width", W).attr("height", H)
.attr("fill", `url(#${OCEAN_ID})`);
const projection = d3.geoEquirectangular().fitSize([W, H], worldFC);
projection.scale(projection.scale() * Math.max(1, DRS_SLIDES_CFG.zoomFactor));
const path = d3.geoPath(projection);
regionFeats = trimOutlierPolygons(regionKey, regionFeats, projection, W, H);
const scene = svg.append("g").attr("class", "drs-scene-pan");
scene.append("g")
.attr("class", "drs-land")
.selectAll("path")
.data(features)
.enter()
.append("path")
.attr("d", path);
if (DRS_SLIDES_CFG.landTextureOn){
scene.append("g")
.attr("class", "drs-land-texture")
.append("rect")
.attr("x", 0).attr("y", 0)
.attr("width", W).attr("height", H)
.attr("filter", `url(#${LANDTEX_ID})`)
.attr("fill", "#ffffff")
.attr("opacity", DRS_SLIDES_CFG.landTextureOpacity)
.attr("pointer-events", "none");
}
const gHiFill = scene.append("g").attr("class", "drs-hi-fill");
const gHiOutline = scene.append("g").attr("class", "drs-hi-outline");
const gHiHalo = scene.append("g").attr("class", "drs-hi-pulse");
gHiFill.selectAll("path")
.data(regionFeats)
.enter()
.append("path")
.attr("d", path)
.attr("fill", `url(#${DOTS_ID})`)
.attr("fill-opacity", DRS_SLIDES_CFG.hiDotOpacity);
gHiOutline.selectAll("path")
.data(regionFeats)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "none")
.attr("stroke", DRS_SLIDES_CFG.hiColor)
.attr("stroke-width", DRS_SLIDES_CFG.hiOutlineWidth)
.attr("vector-effect", "non-scaling-stroke")
.attr("filter", DRS_SLIDES_CFG.glowOn ? `url(#${GLOW_ID})` : null)
.attr("stroke-opacity", 0.9);
gHiHalo.selectAll("path")
.data(regionFeats)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "none")
.attr("stroke", DRS_SLIDES_CFG.hiColor)
.attr("stroke-width", 7)
.attr("vector-effect", "non-scaling-stroke")
.attr("filter", DRS_SLIDES_CFG.glowOn ? `url(#${GLOW_ID})` : null)
.attr("opacity", 0.10);
if (DRS_SLIDES_CFG.panToCenter && regionFeats.length){
const regionFC = { type: "FeatureCollection", features: regionFeats };
const rb = path.bounds(regionFC);
const rcx = (rb[0][0] + rb[1][0]) / 2 + (DRS_SLIDES_CFG.regionCenterNudge.x || 0);
const rcy = (rb[0][1] + rb[1][1]) / 2 + (DRS_SLIDES_CFG.regionCenterNudge.y || 0);
let tx = (W / 2) - rcx;
let ty = (H / 2) - rcy;
const wb = path.bounds(worldFC);
const pad = Math.max(0, DRS_SLIDES_CFG.panEdgePaddingPx);
const txMin = (W - (wb[1][0] + pad));
const txMax = (-(wb[0][0] - pad));
const tyMin = (H - (wb[1][1] + pad));
const tyMax = (-(wb[0][1] - pad));
tx = clamp(tx, txMin, txMax);
ty = clamp(ty, tyMin, tyMax);
scene.attr("transform", `translate(${tx},${ty})`);
}
if (DRS_SLIDES_CFG.oceanVignetteOn){
svg.append("rect")
.attr("x", 0).attr("y", 0)
.attr("width", W).attr("height", H)
.attr("fill", `url(#${VIGNETTE_ID})`)
.attr("pointer-events", "none");
}
if (DRS_SLIDES_CFG.oceanLightSweepOn){
svg.append("rect")
.attr("x", 0).attr("y", 0)
.attr("width", W).attr("height", H)
.attr("fill", `url(#${SWEEP_ID})`)
.attr("opacity", 1)
.attr("pointer-events", "none");
}
if (DRS_SLIDES_CFG.filmGrainOn){
svg.append("rect")
.attr("x", 0).attr("y", 0)
.attr("width", W).attr("height", H)
.attr("filter", `url(#${GRAIN_ID})`)
.attr("fill", "#ffffff")
.attr("opacity", DRS_SLIDES_CFG.filmGrainOpacity)
.attr("pointer-events", "none");
}
return svg.node();
}
/* =========================
LABEL LIST (flex column)
========================= */
function ensureLabelsOverlay(container, orderKeys){
let wrap = container.querySelector(":scope > .drs-region-labels");
if (!wrap){
wrap = document.createElement("div");
wrap.className = "drs-region-labels";
container.appendChild(wrap);
}
const gap = Number(DRS_SLIDES_CFG.labels?.gapPx ?? 8);
const inactiveOpacity = Number(DRS_SLIDES_CFG.labels?.inactiveOpacity ?? 0.4);
const underlineOutMs = Number(DRS_SLIDES_CFG.labels?.underlineOutMs ?? 400);
container.style.setProperty("--drs-label-gap", `${gap}px`);
container.style.setProperty("--drs-label-opacity-inactive", `${inactiveOpacity}`);
container.style.setProperty("--drs-underline-in-ms", `${Math.max(300, DRS_SLIDES_CFG.slideDurationMs)}`);
container.style.setProperty("--drs-underline-out-ms", `${Math.max(120, underlineOutMs)}`);
wrap.innerHTML = "";
const nodesByKey = new Map();
orderKeys.forEach((k) => {
const r = getRegion(k);
const item = document.createElement("div");
item.className = "drs-region-label h4";
item.dataset.regionKey = k;
const txt = document.createElement("div");
txt.className = "drs-region-label-text";
txt.textContent = r?.label || k;
const underline = document.createElement("div");
underline.className = "drs-underline";
underline.style.width = "100%";
item.style.width = "fit-content";
item.style.maxWidth = "max-content";
item.appendChild(txt);
item.appendChild(underline);
wrap.appendChild(item);
nodesByKey.set(k, item);
});
return { wrap, nodesByKey };
}
function setActiveLabel(nodesByKey, activeKey){
nodesByKey.forEach((node, k) => node.classList.toggle("is-active", k === activeKey));
}
/* =========================
INIT / REBUILD (responsive)
========================= */
async function buildAllSlides(el){
const { W, H } = getContainerSize(el);
clearContainer(el);
el.style.setProperty("--drs-fade-ms", String(DRS_SLIDES_CFG.fadeMs));
const order = DRS_SLIDES_CFG.regionOrder.map(s => s.trim()).filter(Boolean);
const { wrap: labelsWrap, nodesByKey } = ensureLabelsOverlay(el, order);
const slides = [];
const keys = [];
for (const regionKey of order){
const uid = `${regionKey}-${Math.random().toString(16).slice(2)}`;
const svg = await buildMapSlideSVG({ regionKey, uid, W, H });
slides.push(svg);
keys.push(regionKey);
el.appendChild(svg);
}
el.appendChild(labelsWrap);
return { slides, keys, nodesByKey, labelsWrap, W, H };
}
function stopRotation(el){
if (el._drsTimer){
clearInterval(el._drsTimer);
el._drsTimer = null;
}
}
function startRotation(el, state){
stopRotation(el);
const { slides, keys, nodesByKey } = state;
if (!slides || !slides.length) return;
let idx = 0;
slides.forEach((s, i) => s.classList.toggle("is-active", i === 0));
setActiveLabel(nodesByKey, keys[0]);
el._drsTimer = setInterval(() => {
slides[idx].classList.remove("is-active");
idx = (idx + 1) % slides.length;
slides[idx].classList.add("is-active");
setActiveLabel(nodesByKey, keys[idx]);
}, Math.max(1200, DRS_SLIDES_CFG.slideDurationMs));
}
function debounce(fn, wait){
let t = null;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn(...args), wait);
};
}
async function initDRSRegionSlides(container){
const el = typeof container === "string" ? document.querySelector(container) : container;
if (!el) return;
if (el._drsSlidesInit) return;
el._drsSlidesInit = true;
const doBuild = async () => {
const size = getContainerSize(el);
el._drsLastSize = size;
const state = await buildAllSlides(el);
el._drsState = state;
startRotation(el, state);
};
await doBuild();
const onResize = debounce(async () => {
const prev = el._drsLastSize || { W: 0, H: 0 };
const next = getContainerSize(el);
const dW = Math.abs(next.W - prev.W);
const dH = Math.abs(next.H - prev.H);
if (dW < 2 && dH < 2) return;
el._drsLastSize = next;
stopRotation(el);
const state = await buildAllSlides(el);
el._drsState = state;
startRotation(el, state);
}, DRS_SLIDES_CFG.resizeDebounceMs);
if ("ResizeObserver" in window){
const ro = new ResizeObserver(onResize);
ro.observe(el);
el._drsResizeObserver = ro;
} else {
window.addEventListener("resize", onResize, { passive: true });
el._drsWindowResize = onResize;
}
}
/* auto init all .drs-map */
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".drs-map").forEach(initDRSRegionSlides);
});
</script>Our Projects
Vertical Direct Chill Caster Revamp
Dec 2025 - Feb 2026 | Kingdom of Bahrain
Relocation of Billet Sawing Plant
Middle East | 2020
New Batch Homogenizing Furnace
June - October 2025 | Kingdom of Bahrain
Vertical Direct Chill Caster Revamp
Feb 2026 - Present (Target Handover March 2026) | Kingdom of Bahrain
Billet Handling Plant Installation
2021 | Middle East
Furnace Door Refurbishment
2022 | Middle East
Furnace Door Refurbishment

Billet Handling Plant Installation

Vertical Direct Chill Caster Revamp

Work With Us
Let’s Build your next project
Based in the UAE. Operating Internationally.
Based in the UAE.
Operating Internationally.
Trusted by Customers






Industrial Components, Equipment and Fabricated Solutions

Mechanical Components
Precision-engineered mechanical parts supporting casthouse and industrial equipment, supplied with quality assurance for demanding operating environments.
Electrical & Automation Equipment
Electrical systems and automation components sourced to OEM standards, supporting reliable integration and long-term plant performance.
Fabricated Structural Items
Custom-fabricated steel and industrial assemblies built to specification, supporting installations, upgrades and replacement programmes.
Tools & Industrial Consumables
Site tools, PPE and consumables supplied to support maintenance, shutdowns and ongoing operations with consistent availability.









