text: const isHoloJs = typeof navigator.holojs !== 'undefined';
  const canvas = document.createElement(isHoloJs ? 'canvasvr' : 'canvas');
  
  var camera, scene, renderer;
  var attractor, light;
  
  var x = 15 * Math.random();
  var y = 15 * Math.random();
  var z = 15 * Math.random();
  
  var scale = .02; // for reducing overall displayed size
  var speed = 5; // integer, increase for faster visualization
  
  var steps = 100000;
  var current = 1;
  var shown = 10000;
  
  var beta = 8 / 3;
  var rho = 28;
  var sigma = 10;
  
  var dt = .005;
  
  init();
  
  function draw() {
  
      var geometry = attractor.geometry;
  
      geometry.attributes.position.array.copyWithin(3);
      geometry.attributes.color.array.copyWithin(3);
  
      if (current < steps) {
  
          var dx = sigma * (y - x) * dt;
          var dy = (x * (rho - z) - y) * dt;
          var dz = (x * y - beta * z) * dt;
  
          x += dx;
          y += dy;
          z += dz;
  
          geometry.attributes.position.set([scale * x, scale * y, scale * z], 0);
  
          light.color.setHSL(current / steps, 1, .5);
  
          geometry.attributes.color.set(light.color.toArray(), 0);
  
      }
  
      if (current < steps + shown) {
  
          current++;
  
      } else {
  
          current = 0;
  
      }
  
  }
  
  function init() {
  
      scene = new THREE.Scene();
  
      camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 10);
  
      //
  
      var geometry = new THREE.BufferGeometry();
  
      var positions = new Float32Array(3 * shown);
  
      for (var i = 0; i < positions.length; i += 3) {
  
          positions.set([scale * x, scale * y, scale * z], i);
  
      }
  
      geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
  
      var colors = new Float32Array(3 * shown);
  
      for (var i = 0; i < positions.length; i += 3) {
  
          colors.set([1, 0, 0], i);
  
      }
  
      geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));
  
      var material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors });
  
      attractor = new THREE.Line(geometry, material);
      attractor.position.set(0, 1.5, - 2);
      attractor.frustumCulled = false; // critical to avoid blackouts!
      scene.add(attractor);
  
      //
  
      light = new THREE.PointLight(0xffffff, 1);
      light.distance = 2;
      attractor.add(light);
  
      var ground = new THREE.Mesh(
          new THREE.PlaneBufferGeometry(10, 10),
          new THREE.MeshPhongMaterial()
      );
      ground.geometry.rotateX(- 90 * Math.PI / 180);
      scene.add(ground);
  
      //
  
      renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.vr.enabled = true;
  
      //
  
      window.addEventListener('resize', onWindowResize, false);
  
      renderer.setAnimationLoop(render);
  
      window.getVRDisplays().then(
          function (value) {
              if (value.length > 0) {
                  renderer.vr.enabled = true;
                  renderer.vr.setDevice(value[0]);
                  value[0].requestPresent([{ source: renderer.domElement }]);
              }
          });
  
  }
  
  function onWindowResize() {
  
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
  
      renderer.setSize(window.innerWidth, window.innerHeight);
  
  }
  
  function render() {
  
      for (var i = 0; i < speed; i++) draw();
  
      attractor.geometry.attributes.position.needsUpdate = true;
      attractor.geometry.attributes.color.needsUpdate = true;
      attractor.rotation.z += .001;
  
      renderer.render(scene, camera);
  
  }
  