===== ISTEM =====
Solve the following programming task.

TASK: Deep Clone an Object

Write a function 'deepClone(obj)' that deeply copies a given JavaScript object or array (including nested objects, arrays and primitives) without sharing references. It must also clone Date and RegExp objects.

STARTER CODE (javascript):
function deepClone(obj) {
  // Write your code here
}

module.exports = { deepClone };


RULES:
- Keep the function name and signature EXACTLY as given.
- Return working code only. No explanations.
- Put the code in a single ``` block.
- Try to solve it first. If you genuinely cannot, write only this single
  line instead of producing faulty code: CANNOT_SOLVE

===== HAM YANIT =====
```javascript
function deepClone(obj) {
  const seen = new WeakMap();

  function copyProperties(source, target, skipKeys) {
    const descriptors = Object.getOwnPropertyDescriptors(source);

    for (const key of Reflect.ownKeys(descriptors)) {
      if (skipKeys && skipKeys.has(key)) continue;

      const descriptor = descriptors[key];
      if ("value" in descriptor) {
        descriptor.value = clone(descriptor.value);
      }
    }

    Object.defineProperties(target, descriptors);
  }

  function clone(value) {
    if (value === null || typeof value !== "object") {
      return value;
    }

    if (seen.has(value)) {
      return seen.get(value);
    }

    let result;

    if (value instanceof Date) {
      result = new Date(value.getTime());
      seen.set(value, result);
      copyProperties(value, result);
      return result;
    }

    if (value instanceof RegExp) {
      result = new RegExp(value.source, value.flags);
      result.lastIndex = value.lastIndex;
      seen.set(value, result);
      copyProperties(value, result, new Set(["lastIndex"]));
      return result;
    }

    if (value instanceof Map) {
      result = new Map();
      seen.set(value, result);
      value.forEach((mapValue, mapKey) => {
        result.set(clone(mapKey), clone(mapValue));
      });
      copyProperties(value, result);
      return result;
    }

    if (value instanceof Set) {
      result = new Set();
      seen.set(value, result);
      value.forEach((setValue) => {
        result.add(clone(setValue));
      });
      copyProperties(value, result);
      return result;
    }

    result = Array.isArray(value)
      ? new Array(value.length)
      : Object.create(Object.getPrototypeOf(value));

    seen.set(value, result);
    copyProperties(value, result);

    return result;
  }

  return clone(obj);
}

module.exports = { deepClone };
```