<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Tablero de Ajedrez</title>

<style>
body {
  background:#1e1e1e;
  display:flex;
  justify-content:center;
  align-items:center;
  height:100vh;
  margin:0;
}

#board {
  display:grid;
  grid-template-columns:repeat(8, 60px);
  grid-template-rows:repeat(8, 60px);
  border:3px solid #333;
}

.square {
  width:60px;
  height:60px;
  display:flex;
  justify-content:center;
  align-items:center;
  font-size:36px;
}

.light { background:#EEEED2; }
.dark  { background:#769656; }
</style>
</head>

<body>

<div id="board"></div>

<script>
const board = document.getElementById("board");

const pieces = [
  ["♜","♞","♝","♛","♚","♝","♞","♜"],
  ["♟","♟","♟","♟","♟","♟","♟","♟"],
  ["","","","","","","",""],
  ["","","","","","","",""],
  ["","","","","","","",""],
  ["","","","","","","",""],
  ["♙","♙","♙","♙","♙","♙","♙","♙"],
  ["♖","♘","♗","♕","♔","♗","♘","♖"]
];

for(let r=0;r<8;r++){
  for(let c=0;c<8;c++){
    const sq = document.createElement("div");
    sq.className = "square " + ((r+c)%2===0 ? "light":"dark");
    sq.textContent = pieces[r][c];
    board.appendChild(sq);
  }
}
</script>

</body>
</html>





window.layout = angular.module("layout", ["ui.router"]);

window.layout.config([
  "$stateProvider",
  "$urlRouterProvider",
  "$provide",
  function($stateProvider, $urlRouterProvider, $provide) {

    $provide.factory("$stateProvider", function () {
      return $stateProvider;
    });

    $provide.factory("$urlRouterProvider", function () {
      return $urlRouterProvider;
    });
}]);

window.layout.service('RouteMonitorService', ['$rootScope', function($rootScope) {
    
    var arrancado = false;

    this.iniciar = function(callback) {
        if (arrancado) return; 
        RouteObserverLib.getInstance().init(
            new AngularJsFactory($rootScope), 
            callback
        );

        arrancado = true;
    };
}]);

window.layout.run([
  "$stateProvider",
  "$urlRouterProvider",
  "$rootScope",
  "RouteMonitorService",
  function($stateProvider, $urlRouterProvider, $rootScope, RouteMonitorService) { 
    $urlRouterProvider.otherwise("/inicio");

    $stateProvider
      .state('inicio', {
        url: "/inicio",
        templateUrl: "lib/inicio.html" 
      })
      .state('productos', {
        url: "/productos",
        templateUrl: "lib/productos.html"
      })
      .state('contacto', {
        url: "/contacto",
        templateUrl: "lib/contacto.html"
      });

    RouteMonitorService.iniciar(function(data) {
      console.log(`*** Servicio Monitor: Ruta -> ${data.name}`);
      $rootScope.rutaActual = data.name;
    })
  }]);

var app = angular.module('miApp', ['layout']);

app.controller('appController', ['$scope', function($scope) {
  $scope.title = "Routing Dinámico";
}]);
<div>
  <h2>Contáctanos</h2>
  <p>Escríbenos a: <strong>AlgunEmail@hotmail.com</strong></p>
  <button ng-click="alert('Enviado!')">Enviar Mensaje</button>
</div>
<div>
  <h2>{{titulo}}</h2>
  <p>Esta es la página principal. El header de arriba no ha cambiado.</p>
</div>
<div>
  <h2>Catálogo de Productos</h2>
  <ul>
    <li ng-repeat="item in lista">{{item}}</li>
  </ul>
</div>
[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
  display: none !important;
}

h1,
p {
  font-family: sans-serif;
}

/* Estilos del Layout Fijo */
.header-fijo {
  background-color: #2c3e50;
  color: white;
  padding: 20px;
  text-align: center;
}

.header-fijo a {
  color: #ecf0f1;
  text-decoration: none;
  font-size: 18px;
  margin: 0 10px;
}

.footer-fijo {
  background-color: #95a5a6;
  padding: 10px;
  text-align: center;
  position: fixed;
  bottom: 0;
  width: 100%;
}

/* Estilos del Contenido Dinámico (ng-view) */
.contenido-dinamico {
  padding: 40px;
  background-color: #ecf0f1;
  min-height: 300px;
  border: 2px dashed #bdc3c7; /* Borde para que veas dónde se inyecta la vista */
  margin: 20px;
}
class RouteObserverLib {
  constructor() {
    this.listener = null;
  }

  static getInstance() {
    if (!RouteObserverLib.instance) {
      RouteObserverLib.instance = new RouteObserverLib();
    }
    return RouteObserverLib.instance;
  }

  init(factory, callback) {
    if (this.listener) {
      this.listener.stopListening();
    }

    this.listener = factory.createListener();
    
    this.listener.startListening(callback);
    console.log('%c RouteObserverLib: Inicializado correctamente.', 'color: green; font-weight: bold;');
  }
}

// Implementación concreta del Listener para AngularJS
class AngularJSListener {
  constructor($rootScope) {
    this.$rootScope = $rootScope;
    this.unsubscribe = null;
  }

  startListening(callback) {
    // Nos suscribimos al evento nativo de UI-Router
    this.unsubscribe = this.$rootScope.$on(
      '$stateChangeSuccess',
      (event, toState, toParams) => {
        const routeData = {
          name: toState.name,
          params: toParams,
          path: toState.url
        };
        callback(routeData);
      }
    );
  }

  stopListening() {
    if (this.unsubscribe) {
      this.unsubscribe();
      console.log('Listener detenido');
    }
  }
}

class AngularJsFactory {
  constructor($rootScope) {
    this.$rootScope = $rootScope;
  }

  createListener() {
    return new AngularJSListener(this.$rootScope);
  }
}