Seguidores

MIS WEBS



miércoles, 9 de octubre de 2019

CREAR UNA CAJA DE CÓDIGO

Caja contenedor de código html, css, js y php

En el siguiente ejercicio tenemos una caja para contener código, dentro de ella os dejaré el código.

Cómo crear una caja para insertar código sin utiliza codepen

  1. Creamos un contenedor en html que llamaremos con el id cajaCode
  2. Dentro de el cuatro botones, cuatro cajas de código y dentro de cada caja un div llamado (#codeHTML, #codeCSS , #codeJS, #codephp) dentro de estos div otros dos: uno con clase numeral y otro con el código class code
  3. Con CSS le damos forma a la caja principal y las diferentes cajas.
  4. Por ultimo con JQuery ocultaremos todas las cajas dejando visible la de #codeHTML
  5. Pondremos a la escucha los botones indicandoles que cuando se haga click en uno de ellos este se haga visible y el resto se oculten.
  6. Crearemos un for para cargar los números del div con clase numeral.

Tan solo tienes que copiar el código siguiente y copiar el tuyo en las cajas con clase code.

                 
 <CajaCodigo>
  <div id="cajaCode">
    
    <input class="tipoCode" type="button" value="html">
    <input class="tipoCode" type="button" value="css">
    <input class="tipoCode" type="button" value="JS">
    <input class="tipoCode" type="button" value="php">
    
    
    <div id="codeHTML">
         <div class="numeral"></div>
 
       <div class="code"><code><pre>
              
************html**********************               
       </pre></code></div>
    </div>
    
    <div id="codeCSS">
         <div class="numeral"></div>

         <div class="code"><code> <pre>
**********************css***************************
          </pre></code></div>
    </div>
    
    <div id="codeJS">
         <div class="numeral"></div> 
         <div class="code"><code><pre>
codeee*****************************************************
         
          
          </pre></code></div>
    </div>
    
    <div id="codephp">
         <div class="numeral"></div> 

  <div class="code"><code><pre>
code***********************
  </pre></code></div>   
      
      
  </div>
 </div>

 <script src="https://code.jquery.com/jquery-3.4.1.js"></script>


          
div#cajaCode{

background: darkslategrey;
border: 15px groove dimgrey;
width:80%;
height:250px;
border-radius:10px;
box-shadow: 5px 5px silver, 
  10px 10px darkgrey, 
  15px 15px grey ;  
}
.numeral{

padding-left:2px;


color:lightslategrey;
font-weight:bolder;
align-content:center;

width:20px;
height: 1900px;
}
.tipoCode{

margin-top:10px;
margin-left:18px;
margin-bottom:0px;
width:15%;
background:silver;

font-size:1.2em;
font-weight: bolder;
color:purple;
}
.tipoCode:hover{
background:darkgrey;
}
.code{
margin-left: 5%;
}
#codeHTML, #codeCSS , #codeJS, #codephp {
width:90%;
height:150px;
margin: 10px auto;
padding:20px;

display: grid;
grid-template-columns: 25px 1fr;
background:black;
color:whitesmoke;

overflow-x: auto;
overflow-y: auto;
white-space: nowrap;


}

@media(max-width: 600px) {

 div#caja{
 width:90%;
 }
 #codeHTML, #codeCSS , #codeJS, #codephp {
 width:80%;
 }
 .code{
 margin-left: 10%;
 }
 input[value='html']{
 width:20%;
 }
}


             

CajaCode();

/*Con esta funcion creamos cajas de código, nuestra caja tiene 
tres botones uno para mostrar el jS/JQ , html y php pomndremos todas las páginas ocultas
cuando pulsemos cada boton saltará una página. hemos creado una funcion llamada numeral
para cargar un div con numeros a la izquierda*/
function CajaCode(){
  /************ocultamos todos los div menos el de html***************/
      $("#codeCSS  , #codeJS, #codephp").hide();
       
      /**ponemos a la escula los botones y le indicamos que se haga visible el nuestro
      ocultando el resto**/
      $("input[value='css']").click(function(){ 
            $("#codeCSS").show();
            $(" #codeHTML , #codeJS, #codephp").hide(); 
      });
      $("#cajaCode input[value='css']").click(function(){ 
            $("#codeCSS").show();
            $(" #codeHTML , #codeJS, #codephp").hide(); 
      });
      $("#cajaCode input[value='html']").click(function(){ 
            $("#codeHTML").show();
            $(" #codeCSS , #codeJS , #codephp").hide(); 
      });
      $("#cajaCode input[value='JS']").click(function(){ 
            $("#codeJS").show();
            $(" #codeCSS , #codeHTML , #codephp").hide(); 
      });
      $("#cajaCode input[value='php']").click(function(){ 
            $("#codephp").show();
            $(" #codeCSS , #codeHTML , #codeJS").hide(); 
      });

/**********creamos un for para llenar el div numeral con numeros de 1 a 100*************/
      $(".numeral").html(C);
      function C(){
         
        let texto="";
        
        for(let i = 1; i<100; i++){
          
          texto += i+"<br>";
          
        }
      return texto;
 
}

}
            
             
             
***************si tienes php cargalo aquí***********************
     

domingo, 22 de septiembre de 2019

parctica load

AJAX CON JQUERY

h2

div

texto del articulo

sábado, 7 de septiembre de 2019

Eventos JQUERY

Scpirts JS Evento JS

OBJETO EVENTO

Un evento es un objeto para java script y como tal tiene sus propiedades y métodos:

    Propiedades

  • target: nos regresa el elemento del DOM que dispara nuestro evento.
  • clientX: es el punto x donde nos encontramos.
  • clientY: es el punto y donde nos encontramos.
  • data: Dato trasmitido al evento utilizando la función bind().

    Métodos

  • sotpPropagation: Evitará la propagación de eventos por el resto de objetos situados en el mismo lugar. Por ejemplo si le decimos que se desencadene el evento tras hacer click en la imagen debemos de tener en cuanta que la imagen pertenece a body que a su vez pertenece al document que a su vez pertenece al html. Tu puedes haber generado un evento para el documento y otro para la imagen. En el siguiente código la imagen responderia al click del body y al click de la imagen.
    $(document).click(function(){
      alert("Body");
    });
    $("img").click(function(){
      alert("Imagen");
    });

    El mismo código utilizando stopPrapagation() solo responderá a la imagen:
    $(document).click(function(){
      alert("Body");
    });
    $("img").click(function(e){
      e.stopPropagation();
      alert("Imagen");
    });

  • preventDefault: Detiene el comportamiento determinado del elemento. Imagina que tu tienes un botón con una etiqueta <a> dentro, si tu haces doble click por defecto te llevara a la dirección que tenga en el atributo href, utilizando preventDefault evitará que al hacer doble click te redireciona.
  • which: Nos regresa un número entero que representa un número unicode que representa la tecla presionada por un keypress

En el siguiente ejercicio utilizamos las propiedades clientX y clientY para ver en que punto de la pagina haces click.

En el siguiente ejemplo creamos una imagen svg con un circulo que seguira el raton. Cuando arrastremos el ratón dentro del svg el circulo irá tras nuestro ratón.

Ejemplo del uso del método stopPropagation, para evitar propagación de eventos

Eventos

Un evento es un desencadenante de una acción (cargarse la pagina, salir de la página, hacer click en un punto, mover el ratón, pasar el ratón por un objeto, pulsar intro...). Una acción es lo que ocurre una vez sucede el evento.

Podemos traducir evento algo que hace un objeto(página, ratón, teclado,formulario) y acción como la qué es lo que pasa cuando luego.

Ejm Cuando hagamos click en una etiqueta a nos llevará a otro pagina. En este caso el evento es hacer click y el evento desencadenado es ir a la pagina xxx.

Los eventos pueden ser de varios tipos:

  • Eventos de ratón:
    • click
    • dbclick
    • mousedown
    • mouseup
    • mouseover
    • mousemove
    • mouseenter
    • mouseeleave
  • Eventos de teclado:
    • keypress
    • keydown
  • Eventos de documento o ventana:
    • load
    • resize
    • scroll
    • unload
  • Eventos de formulario:
    • submit
    • reset
    • change
    • focus
    • blur

Eventos JQuery

Podemos utilizar los evento en jquery de dos formas:

  1. Pasarle una función por parámetros al evento.
    $("div").click(myfuncion);
    fuction myfuncion(){...code...}
  2. Crear una función anónima: $("div").click(function(){....code....});

Ejemplo de eventos con Jquery

EVENTOS JQUERY CON FUNCIÓN toggle() Y hover()

Utilizaremos estas funciones para realizar acciones con los eventos hover y click.

Función hover( cursorInside , cursorOut )

La función hover() desencadenará una acción cuando entre el cursor en el elemento y otra cuando salga de él.

Función toggle()

Lo utilizaremos para trabajar con el evento click, con el aparecerá y desaparecerá nuestro elemento cada vez que hagamos click. Se puede utilizar si queremos hacer una etiqueta <details> personalizada.

Ejemplo de menú con toggle:

Ejemplo de details con imagen personalizada utilizando la función toggle

Funciones next(), bind() on()

next("objeto")

La función next("objeto") nos ayudará a apuntar al próximo objeto que determinemos dentro del actual. Por ejemplo Si le decimos $("article").next("p") apuntará a la primera etiqueta p de cada articulo.

bind("desencadenanteEvento", data, open)

La función bind está en desuso actualmente utilizaremos .on("eventos", acción).

Si deseamos que un obejeto responda a dos o mas eventos (click, hover..) y al responder a ellos desencadene la misma función podemos utilizar bind().

Hasta el momento teniamos que hacer lo siguiente: $("p").click(funcionA).hover(funcionA)

Con bing lo podemos hacer bind("click hover", data, miFuncion)

data será un dato o variable con un dato que le pasamos a nuestra variable

.on("evento/os", funciónAcciónDesencadenada)

En los eventos podemos poner tantos eventos como deseemos que desencadenen nuestra acción, para ello los nombraremos separados con espcacios:

Ejm de múltiples eventos
.on("click dbclick scroll", funciónAcciónDesencadenada)
Ejemplo de eventos con diferentes funciones:
$('.h2').on({ click:hacerclick, mouseover: hacerhover});

function hacerclick(e) {
    e.preventDefault();
    console.log('has hecho click');
}
function hacerhover() {
    console.log('pasó el ratón');
}
                                    

Delegación de eventos

La delegación de eventos es una propiedad del objeto evento que nos puede resultar muy util para identificar el elemento del DOM que dispara el evento y sus atributos. Saviendo este dato podremos solicitar su modificación posterior mente.

En este ejemplo utilizamos la funcion .on() y le indicamos en primer lugar el elemento padre desde el que deseamos empezar la búsqueda $("ElementoPadre") y dentro de la función on le pasaremos por parámetros, los eventos desencadenantes de la acción, el hijo que debe identificarnos y por ultimo acción que desencadena.

$("ElementoPadre").on("eventos","ElementoHijo", function(){ $(this).attr("id") });

En el siguiente ejemplo nos regresará por consola la propiedad class de cada objeto del DOM por el que pasemos el ratón.

$("*").hover(function(e){console.log(e.target.className);});
Ejemplo de función next()

See the Pen función next() de JQ by CVDGP (@cvdgp) on CodePen.

Ejemplo de función .on("evento/s", acción):

En el siguiente ejemplo crearemos dos imágenes, cuando hagamos click o carguemos la página copiara la ruta de la imagen1 y se la dará a la imagen 2, poniendola visible (Show), cuando pasemos el ratón por la imágen 2 esta desaparecerá, utilizaremos el método stopPropagation() del objeto evento para evitar que se propague en otro objetos como el body:

viernes, 28 de junio de 2019

SVG




GENERA GRAFICOS VECTORIALES CON <svg>

Un grafico vectorial es un dibujo esclable a cualquier tamaño, es una forma de generar dibujos de una forma muy ligera para el navegador y mucho más simple que canvas. El contenedor sgv es muy útil para gnerar dibujos de textos, circulos, cuadrados.
En primer lugar abriremos una eqiqueta sgv y dentro de ella podrmos incluir el resto de equetas
<text>
Cargaremos textos dentro de nuestro contenedor sgv. Los atributos x e y marcaran el punto en el que se situa nuestro dibujo.El atributo fill lo utilizaremos para indicar el color del relleno.



<rect>
Lo utilizaremos para generar un rectangulo. El atributo stroke sera el borde de nuestra imagen.
<circle>
Crea un circulo, para posicionarlo tenemos los atribuyos cx y cy, para definir el tamaño tenemos el atributo r que representa el rádio de nuestro circulo y para definir el grosor del borde tenemos stroke-width


<line>
Crearemos un linea, x1 y y1 marcará el punto en el que iniciamos nuestra línea, mientras x2 e y2 marca el fin de la línea.
<ellipse>
Es una figura geométrica parecida a un circulo pero no tiene un radio regular. utilizaremos los atributos cx y cy para situar la elipse y utilizaremos rx y ry para darle forma a nuestra elipse.



<polyline>
Una poli linea es un conjunto de líneas, utilizaremos el atributo points para darle los puntos x,y en los que inicia cada línea (points="20,20 40,25 60,40"). En la siguiente imágen crearemos dos polilíneas con un texto superpuesto y un elipse.



Degradados <defs> DEGRADADO CIRCULAR


<tspan>
Podemos utilizar esta etiqueta para insertar textos dentro de una etiqueta text.



martes, 11 de junio de 2019

BorderLayout


BorderLayout (diseño de borde): Dispondremos los objetos utilizando los puntos cardinales como referencia. Los componentes que introduzcamos en cada una de las zonas se harán lo suficiente mente grandes como para llenar la zona a la que pertenecen.






BorderLayout tiene una característica peculiar y es que los componentes que introduzcamos en cada una de las zonas se harán lo suficiente mente grandes como para llenar la cuadricula en la que se encuentra.

Ejemplo con el constructor por defecto BorderLayout():


class Panel extends JPanel{
             public Panel() {
                    setLayout(new BorderLayout());
                    add(new JButton ("NORTE"),BorderLayout.NORTH);
                    add(new JButton ("CENTRO"),BorderLayout.CENTER);
                    add(new JButton ("OUESTE"),BorderLayout.EAST);
                    add(new JButton("SUR"),BorderLayout.SOUTH);
                    add(new JButton("ESTE"),BorderLayout.WEST);
             }
  }







Existe un segundo constructor que nos permite dar espacio entre los componentes

BorderLayout(espacio horizontal entre componentes, espacio vertical entre componentes )

class Panel extends JPanel{

             public Panel() {
                    setLayout(new BorderLayout(10,20));
                    add(new JButton ("NORTE"),BorderLayout.NORTH);
                    add(new JButton ("CENTRO"),BorderLayout.CENTER);
                    add(new JButton ("OUESTE"),BorderLayout.EAST);
                    add(new JButton("SUR"),BorderLayout.SOUTH);
                    add(new JButton("ESTE"),BorderLayout.WEST);
             }
       }



martes, 4 de junio de 2019

Etiquetas En linea Html5

Etiquetas inline

Son aquellas que se encuentran dentro de un párrafo y no generan salto de línea (<p></p>), estas etiquetas no subdividen el párrafo en partes, su función es informar al buscador el significado de las palabras e importancia sobre el resto.

Etiquetas in line

ETIQUETA USO
<strong> Lo veremos en el navegador como texto en negrita, pero el sentido para html es que esa en concreto es una palabra muy importante para nosotros, es una palabra clave
<em> Lo utilizaremos para dar énfasis a una palabra o conjunto de palabras, se mostrará en el navegador como cursiva
<small> Lo utilizaremos dentro de un footer siempre y su utilidad es indicar al browser que se trata de un texto legal.
<cite> Para realizar citas a autores.
<dfn> Se utiliza para hacerdefiniciones.
<i> Crea una caja en línea y se utiliza paraestilos y colores en el texto que estmos escribiendo, no tiene sentido semantico.
<code> Le indicamos que dentro de esta etiqueta eixite un trozo de código programación.
<abbr> Indicamos que se trata de una abreviatura
<data> Para datos de una estadística o etc.
<br> Salto de línea,no es necesario cerrarlo
<q> cita a libros, videos, canciones...
<del> Texto eliminado, lo podemos utilizar para precios antiguos, lo veremos como un texto tachado
<pre> Matiene el formato anterior del texto.
<sub> Subindice ejem. 259 /50
<sup> Poner potenciales. ejm. 150 25.
<time> fechas
<time datetime "2018-03-30" pubdate>
<mark> resaltado de texto subrayador.
<kdb> Cuando hacemos alusión a atajos de teclado o teclas del teclado(alt,sift, enter, control+spr...).>
<span> No tienen sentido semántico, la única utilidad que tiene es la de seleccionar una palabra o conjunto de palabras para posteriormente modificarlas con css o JavaScript.
<a> hipervinculo, palabra ancla o ancorText
<a href= "RUTA" target="_black" rel="follow"> ...texto... </a>
lo utilizaremos para redirecciones a una url , target= “_blank” abrirá la URL en otra pestaña nueva y rel follow o nofollow determinara el tipo de nelace que hacemos.
<address> Lo utilizaremos dentro de un footer y se usa para datos personales emali,teléfonos,dni
<b> Fuente en negrita esta etiqueta esta desaconsejada en html5 se aconseja utilizar estilos css como font-weight: bolder;. Cabe recalcar que no es lo mismo que la etiqueta Strong que proporciona un sentido semántico de énfasis.

PARADIGMA DE LA PROGRAMACIÓN GENÉRICA EN JAVA


¿Qué es la programación genérica?


La programación genérica surge a partir de la versión 5.0 de java en el año 2004. Es un paradigma informático que nos indica que tenemos que crear un código que podamos reutilizar para otros objetos de diverso tipo. Por ejemplo el objeto ArrayList lo podemos utilizar para manejar y reutilizar objetos de tipo String, coche, moto….
Le pasaríamos por parámetros entre corchetes angulares <> el objeto al objeto ArrayList. Así conseguimos reutilizar el objeto ArrayList con cualquier objeto. El objeto pasado al ArrayList entre corchetes angulares <> se llama parámetro de tipo.



paradigma de la programación generica en java
parámetros de tipo en programación genérica de java




Tenemos que tener en cuenta que no podemos pasar como parámetro tipo una clase primitiva(int, long, boolean,double…)



VENTAJA DE LA PROGRAMACIÓN GENÉRICA


Esto mismo lo podríamos realizar utilizando una propiedad de java que es la herencia pero tendríamos que realizar uso continuo del casting. Por otra parte cuando heredas un objeto y le haces un casting el fallo no saldría en tiempo de compilación si no en tiempo de ejecución y esto haría más complicado controlar los posibles errores. Todo esto hace mas complejo de nuestro código.

Utilizar la programación genérica:

·         Hace nuestro código más sencillo.
·         Podemos reutilizar código de una forma más rápida.
·         Los errores nos acontecerán en la compilación, el IDE (entorno desarrollo) nos avisará y podremos rectificar antes de programar más líneas de código.

·         Al pasar un parámetro tipo queda más claro en nuestro código que tipo de dato estamos manejando.




Como crear mi clase genérica



Crearremos una clase y le pasarémos por parámetro tipo nuestro objeto. Es una buena praxis el pasarle una letra mayúscula que suele ser T, U,K. Podemos utilizar cualquier otra y no afectará a nuestro código pero es aconsejable pasarle estas para que el resto de programadores identifiquen que son.
public class ClaseGenericaaaaaaa <Q>{
}

Creamos una variable de tipo de tipo Q y un constructor.

public class ClaseGenericaaaaaaa <Q>{
       private Q xxxx;
       public ClaseGenericaaaaaaa() {
             xxxx = null;
       }
}




Ahora creamos los MÉTODOS GETTER Y SETTER

public class ClaseGenericaaaaaaa <Q>{
       private Q xxxx;
       //**constructor**
       public ClaseGenericaaaaaaa() {
             xxxx = null;
       }//**setter
       public void setClaseGenericaaaaaaa (Q xxxx ) {
             this.xxxx = xxxx;         
       }//getter
       public Q   getClaseGenericaaaaaaa () {
             return xxxx;
       }
}







Nos iremos al método main crearemos un objeto de la clase ClaseGenericaaaaaaa al que le pasamos por parámetro de tipo un String.


public class eSTOva {
       public static void main(String[] args) {
//le decimos que Q será un String
ClaseGenericaaaaaaa <String> CrearString = new ClaseGenericaaaaaaa<String>();
             //establecemos dato guardado
             CrearString.setClaseGenericaaaaaaa("DDDDDDDDDDDDDDD");
             //lo recuperamos para imprimirlo
             System.out.println(CrearString.getClaseGenericaaaaaaa());
       }
}





Antes le pasamos un parámetro tipo de String, pero puede ser un File o cualquier otro que deseemos.

public class eSTOva {
       public static void main(String[] args) {
ClaseGenericaaaaaaa <String> CrearString = new ClaseGenericaaaaaaa<String>();
ClaseGenericaaaaaaa <File> RutaAcceso = new ClaseGenericaaaaaaa<File>();

       CrearString.setClaseGenericaaaaaaa("DDDDDDDDDDDDDDD");
       RutaAcceso.setClaseGenericaaaaaaa(new File("C:"+File.separator+"Users"                                            +File.separator+"dagip"
                                        +File.separator+"Desktop"                                                       +File.separator+"BOGEER"                                                        +File.separator+"imagenes"
                                        +File.separator+"video"));

                    //nos regresa un String
             System.out.println(CrearString.getClaseGenericaaaaaaa());
                    //nos regresa un File
             System.out.println(RutaAcceso.getClaseGenericaaaaaaa());
       }
}





Al ser un objeto de tipo File podemos decir lo siguiente, porque posee métodos de la clase File. Tenemos las ventajas de la herencia sin tener los problemas del casting.


System.out.println(RutaAcceso.getClaseGenericaaaaaaa().getAbsolutePath());







CREAR UN MÉTODO GENÉRICO


Es un método que podemos utilizar con cualquier tipo de objeto, no es necesario que se generado dentro de una clase genérica, lo podremos construir en cualquier tipo de clase. Y se adptará al objeto que le pasemos por parámetro tipo. No se le puede pasar un tipo de dato primitivo.
Su sintaxis es similar a la utilizada en una clase genérerica.

public static <K> String getdato (K variable){
             return "Este es tu dato     " + variable;
       }



Si deseamos que nos regrese un dato sin especificar que sea igual al objeto que recibe
public static <K> K getdato (K variable){
             return "Este es tu dato     " + variable;
       }



Ahora lo utilizamos, nos imprimiría en la ventana de inmediato lo que tenemos en ambas variables a pesar que una es File y la otra String y sin hacer un casting:


System.out.println(eSTOva.getdato(CrearString));
System.out.println(eSTOva.getdato(RutaAcceso));





HERENCIA DE CLASES GENÉRICAS Y TIPOS COMODÍN



La herencia en las clases genéricas no es igual al que tiene en el resto de clases. Esta anomalía a la hora de heredar de una clase genérica nos obligar
Recordemos que en una clase normal existía el pricipio de sustitución


Principio de sustitución: Se puede utilizar un objeto de una sub clase siempre que el programa espere un objeto de la Superclase. Por lo que un objeto se puede comportar de diferente manera dependiendo del contexto. Podremos utilizarlo siempre que podamos decir ES UN. En el siguiente caso podemos decir cerdo es carne y pollo es carne.

             Carne [] Cerdo=new Carne[5];
                Carne [] Pollo =new Carne[6];
                Carne [] ArticulosCarne=new Carne[11];
for (int x=0;  x<5;  x++) {ArticulosCarne[x]= Cerdo[x];}
for (int y=5,x=0;y<11 && x<6;y++,x++){ArticulosCarne[y]=Pollo[x];}



En las clases genéricas no existe relación entre los objetos. La Clase <carner> es un objeto con unas propiedades y métodos, la Clase <cerdo> es otro objeto independiente con unas propiedades y métodos, pero no tienen ningún nexo en común.


Para tener una salida a esto tenemos la posibilidad de crear un método genérico en la clase padre y pasarle por parámetros la clase hija. Luego iremos al método main y llamaremos a ese método.

ClaseGenericaaaaaaa < ArticulosCarne []> CrearString = new ClaseGenericaaaaaaa< ArticulosCarne []>();
ClaseGenericaaaaaaa < Pollo []> CrearString = new ClaseGenericaaaaaaa< Pollo []>();
ClaseGenericaaaaaaa < Cerdo []> CrearString = new ClaseGenericaaaaaaa< Cerdo []>();

Creamos el método diciéndole que hereda de ArticulosCarne

public static void getid(ClaseGenericaaaaaaa <? extends ArticulosCarne > p ) {
              Pollo heredaCarne = p.getClaseGenericaaaaaaa();
             System.out.print(nod);
       }


Ahora podemos utilizar el getClaseGenericaaaaaaa() en el método main.


             NUMERO1.setClaseGenericaaaaaaa(Pollo ());

Buscar este blog

Sandisk y Western Digital