Bitsums - Versión para impresión +- Allied Modders en español (https://amxmodx-es.com) +-- Foro: AMX Mod X - Scripting (https://amxmodx-es.com/Forum-AMX-Mod-X-Scripting) +--- Foro: Tutoriales / Guias (https://amxmodx-es.com/Forum-Tutoriales-Guias) +--- Tema: Bitsums (/Thread-Bitsums) |
Bitsums - roccoxx - 08/10/2013 ola k ase, ahora les mostrare lo que es un tutorial. thread original:https://forums.alliedmods.net/showthread.php?t=139916 autor:Bugsy traductor:roccoxx bueno, este traduccion es de un tutorial, el cual se basa el los conocimientos basico de como usar los bits - bit..bueno lo traduci linea por linea espero que les sirva. ¿Qué es un campo de bits? conocidos en ingles como bit-field) Un campo de bits es una serie de bits continuos dentro de una celda de memoria(no un array).El número de bits en un determinado campo de bits se determina por el número de bytes asignados para el tipo de datos que se utiliza. Por defecto, todos los bits en un campo de bits son 0. Cuando no hay bits son 1 en un determinado campo de bits, el valor resultante será 0. Si uno o más bits son 1 dentro de un campo de bits, el número resultante será distinto de cero. AMX-X solo tiene 1 tipo de datos que es una "cadena" de 4 byte, por lo que es limitado a 32-bits en un único campo de bits. ejemplos de tamaños en los campos de bits e.e 1-bytes = 8 bits == 0000 0000 2-bytes = 16 bits = 0000 0000 0000 0000 4-bytes = 32 bits = 0000 0000 0000 0000 0000 0000 0000 0000 ¿Cómo son los números almacenados en un ordenador? Toda la información en un ordenador se almacena en la memoria (RAM, ROM, disco duro, memoria flash, etc). En el nivel más bajo, la memoria consta de muchos muchos MUCHOS interruptores de encendido y apagado (conocidos como bits). Un valor entero que es el resultado de una combinación de bit (s) que se establecen como 1 o 0 xD cada bit corresponde a una potencia de 2. aca les muestro un ejemplo rapido de 8 bits para que vean cómo los bits forman un número: el orden de los bits es el siguiente: 7654 3210 Los valores inferiores corresponden a cada uno de esos bits.Como vos podes ver, si un bit es 1 en un campo de bits, el valor entero se incrementa por el valor correspondiente para la respectiva potencia de 2. 1 === 2 potencia de 0 - almacenado en bits: 0000 0001 (representación binaria) 2 === 2 potencia de 1 - Almacenado en bits: 0000 0010 4 === 2 potencia de 2 - Almacenado en bits: 0000 0100 8 === 2 potencia de 3 - Almacenado en bits: 0000 1000 16 == 2 de potencia de 4 - Almacenado en bits: 0001 0000 32 == 2 de potencia de 5 - Almacenado en bits: 0010 0000 64 == 2 de potencia de 6 - Almacenado en bits: 0100 0000 128 = 2 La capacidad de 7 - Almacenado en bits: 1000 0000 Supongamos que tenemos una variable que contiene el número 97, nuestro campo de bits aparecería como: 0110 0001 miren que los bits 1, 6 y 7 se establecen o.O. nosotros podemos añadir cada número correspondiente (o 2 bits de potencia #) a nuestro número resultante e.e 1 == 2 de potencia de 0 a 1 2 3 4 5 6 == 2 potencia de 5 a 32 7 == 2 de potencia de 6 a 64 8 = O 2 ^ 0 + 2 ^ 6 + 2 ^ 7 = 1 + 32 + 64 = 97 ¿Qué son los operadores a nivel de bits y cómo se utilizan? nota yo pongo comprobar en las descripciones pero si quieren tomenlo como checkiar *& - And *| - Or *^ - Xor (exclusivo O) *~ - Not *<< - Left bit-shift *>> - Right bit-shift Operador: & Función: Y Descripción: Este operador se utiliza para comprobar si y sólo si ambos de los bits correspondientes en los dos operadores son 1. el resultado del campo de bits consistirá en bits (1) que estaban presentes en la misma ubicación dentro de los dos operadores. 15 & 3 = 3 15 = 0000 1111 03 = 0000 0011 03 = 0000 0011 _________________ 145 & 97 = 1 145 = 1001 0001 097 = 0110 0001 001 = 0000 0001 _________________ 255 & 234 = 234 255 = 1111 1111 234 = 1110 1010 234 = 1110 1010 Operador: | Función: O Descripción: Este operador se utiliza para comprobar si uno o ambos bits son 1 dentro de las posiciones de bit correspondientes de los dos operadores. el resultado del campo de bits consistirá en bits (1) que estaban presentes en cualquiera de los operadores para cada ubicación de bit. 15 | 3 = 15 15 = 0000 1111 03 = 0000 0011 15 = 0000 1111 _________________ 145 | 97 = 241 145 = 1001 0001 097 = 0110 0001 241 = 1111 0001 _________________ 255 | 234 = 255 255 = 1111 1111 234 = 1110 1010 255 = 1111 1111 Operador: ^ Función: Xor (O exclusivo) Descripción: Este operador es utilizado para comprobar si los bits correspondientes dentro de los dos operadores son diferentes. La resultante del campo de bit consistirá bits (1) de que eran opuesto (0 y 1 o 1 y 0) en el mismo lugar dentro de los dos operadores. 15 ^ 3 = 12 15 = 0000 1111 03 = 0000 0011 12 = 0000 1100 _________________ 145 ^ 97 = 240 145 = 1001 0001 097 = 0110 0001 240 = 1111 0000 _________________ 255 ^ 234 = 21 255 = 1111 1111 234 = 1110 1010 021 = 0001 0101 Operador: ~ Función: No Descripción: No toma la representación binaria de un número, y convierte los ceros en unos, y unos en ceros. A diferencia de los anteriores tres operadores bit a bit [AND, OR, XOR], no toma solo un operador. 0000 1111 = 15 1111 0000 = ~15 = 240 _________________ 1010 1010 = 170 0101 0101 = ~170 = 85 _________________ Operador: << Función: desplazamiento de bit hacia la izquierda Descripción: Desplazar los bits en el operando de la izquierda por las posiciones de bit especificadas. X << Y Esto quiere decir que se desplazan los bits en el operador x y los bits Y hacia la izquierda. Todos los bits a la izquierda que se encuentran fuera del rango de bits seran descartados. Todos los bits añadidos a la derecha debido al cambio son 0. En este ejemplo se asume una celda de memoria 1-byte para cualquier bit desplazado a la izquierda pasado el 8 º bit son eliminados, si usted está usando una celda de memoria más grande (en AMXX, una celda es de 4 bytes o bits de 32), estos bits seran descartados pero se trasladaron más allá del 8 º bit a los bits 9-32). 15 << 4 015 = 0000 1111 030 = 0001 1110 [Todos los bits se han desplazado una posición] 060 = 0011 1100 [Todos los bits se han desplazado 2 posiciones] 120 = 0111 1000 [Todos los bits se han desplazado 3 posiciones] 240 = 1111 0000 [Todos los bits se han desplazado 4 posiciones] _________________ 209 << 2 209 = 1101 0001 162 = 1010 0010 [Todos los bits se han desplazado 1 posición] 068 = 0100 0100 [Todos los bits se han desplazado 2 posiciones] Operador: >> Función: desplazamiento de bits hacia la derecha Descripción: Desplazar los bits en el operando a la derecha por las posiciones de bit especificadas. X >> y This will shift bits in the X operand Y bits to the right. Esto quiere decir que se desplazan los bits en el operador x y los bits Y hacia derecha. Todos los bits a la derecha que caen fuera del rango de bits, se eliminaran o.O. Todos los bits añadidos a la izquierda debido al desplazamiento, son 0. 15 >> 4 015 = 0000 1111 007 = 0000 0111 [Todos los bits se han desplazado 1 posición] 003 = 0000 0011 [Todos los bits se han desplazado 2 posiciones] 001 = 0000 0001 [Todos los bits se han desplazado 3 posiciones] 000 = 0000 0000 [Todos los bits se han desplazado4 posiciones] _________________ 209 >> 2 209 = 1101 0001 104 = 0110 1000 [Todos los bits se han desplazado 1 posición] 052 = 0011 0100 [Todos los bits se han desplazado 2 posiciones] Operaciones comunes de un campo de bits -Configuración de bit (s) a 1 \ cierto(true) en un campo de bits Esto se hace usando el modo de bit operador OR |. Como se explicó anteriormente, esto establecerá el bit a verdadero(true) si existe en cualquiera de los operadores. Establecer un solo bit iVariable = iVariable | ( 1 << 4 ); 0000 0000 = iVariable (recientemente declarada, valor establecido) 0001 0000 = 1 << 4 0001 0000 = iVariable | ( 1 << 4 ) Establecer múltiples bits en la misma expresión iVariable = iVariable | ( ( 1 << 4 ) | ( 1 << 5 ) ) 0000 0000 = iVariable 0001 0000 = 1 << 4 0010 0000 = 1 << 5 0011 0000 = iVariable | ( ( 1 << 4 ) | ( 1 << 5 ) ) Configuración de bit (s) a 0 \ falso(false) en un campo de bits Esto se hace usando una combinación de bit a bit con el operador y & y el operador no ~. Supongamos un campo de bits con los bits 4 y 5 setiados. iVariable = ( ( 1 << 4 ) | ( 1 << 5 ) ) Supongamos que tenemos que establecer bit 4 a 0 \ falso(false). iVariable = iVariable & ~( 1 << 4 ) 0011 0000 = ( ( 1 << 4 ) | ( 1 << 5 ) ) 1110 1111 = ~( 1 << 4 ) 0010 0000 = ( ( 1 << 4 ) | ( 1 << 5 ) ) & ~( 1 << 4 ) El mismo se puede hacer para establecer múltiples bits a 0 \ falso(false) en una sola expresión. Sólo es necesario bit a bit o los bits que desea establecer en 0. iVariable = iVariable & ~( ( 1 << 4 ) | ( 1 << 5 ) ) Usando campos de bit En un campo de bits se puede establecer el bit (s) a 1, el bit se establece (s) a 0, se comprueba si un bit en particular (s) es 0/1, y se utiliza el entero resultante del campo de bits. Esto hace que a los campos de bits muy utiles y eficientes. Ejemplo 1, utilizando campos de bits como un bool Una aplicación útil es si nosotros queremos almacenar si un jugador es admin cuando se conecta al server. La práctica común es crear una matriz de celdas, utilizando una celda para true \ falso valor de cada jugador. merodo con array - bool e.e Código PHP: new bool: g_IsAdmin[33]; si el id2 y el id6 del jugador son administradores, llos elementos g_IsAdmin [2] y g_IsAdmin [6] seran verdaderos(true), una celda es 4-bytes si usamos una array para este prosito, requiere 132 de memoria(33-celdas 4 veces-bytes) si solo usamos un campo de bit, sólo se declarará una sola celda y puede almacenar la misma información pero con sólo 4 bytes! o.O metodo con campo de bit Código PHP: new g_IsAdmin; //solo necesita una celda de memoria e.e y obtendremos un valor utilizable xD.cuando ( # & 31 ) es usado el valor será igual a la ID del jugador excepto cuando id == 32, cuando id == 32, el valor resultante es 0.En pocas palabras, jugador-id 1-31 se devuelven como normal, pero cuando el ID del jugador es 32, se devuelve 0, así que estamos utilizando esencialmente 0-31 en lugar de 1-32, que es exactamente lo que necesitamos. en la situacion que se explica alla arriba donde la id 2 y 6 del/os jugador/es se refiere a los administradores online, nuestro campo de bits se vería como la siguiente. Si usted se está preguntando por qué los bits no están en la posición basada en la id del jugador, consulte la (id y 31) que se explicó anteriormente. 0000 0000 0000 0000 0000 0000 0100 0100 un bonus por el uso de campos de bits para almacenar bools se puede comprobar rápidamente si los bits están establecidos, o en este caso, si alguno de los administradores esta en línea.Recordemos, si no hay bits son 1 en un determinado campo de bits, el valor resultante es 0; De igual modo, si hay 1 o más bits puestos a 1 en el campo de bits, el número resultante no es cero. Código PHP: if ( g_IsAdmin ) si se utilizo un array, usted tendra que usar un loop(buble), para iterar a través de todos los elementos del array para comprobar si cada valor es 1.Esto es lo que hace que los campos de bits no sólo sean más eficientes en cuanto a la relacion con la memoria, sino también un CPU mas eficiente y más fácil (menos código o.O). Ejemplo 2, bool para un/los index de un/las armas en este ejemplo se muestra como se pueden marcar varias armas en un campo de bits. esto se puede usar en cualquier plugin que se necesite hacer una restriccion a un arma o cualquier api que necesite un valor verdadero/falso para cada arma. esto es posible porque las armas del cs tienen un index que van desde 1-32. en este ejemplo vamos a crear un campo de bits que representen las armas CSW_SG550 [13], CSW_AWP [18], y CSW_G3SG1 [24]. El mayor índice de un arma (primaria \ secundaria) es 30 (P90) por lo que no tiene que preocuparse acerca de la utilización (# & 31) ni nada de eso. g_Weapons = ( 1 << CSW_SG550 ) | ( 1 << CSW_AWP ) | ( 1 << CSW_G3SG1 ); Esto es lo que ocurre con la operación anterior 0000 0000 0000 0000 0000 0000 0000 0001 = 1(Cómo 1 está representado en el nivel de bit. Vamos a cambiar este bit para cada posición de bit en el index del arma) 0000 0000 0000 0000 0010 0000 0000 0000 = 1 << CSW_SG550 (1 fue desplazado a la izquierda por CSW_SG550 [13]) 0000 0000 0000 0100 0000 0000 0000 0000 = 1 << CSW_AWP (1 fue desplazado a la izquierda por CSW_AWP [18]) 0000 0001 0000 0000 0000 0000 0000 0000 = 1 << CSW_G3SG1 (1 fue desplazado a la izquierda por CSW_G3SG1 [24]) 0000 0001 0000 0100 0010 0000 0000 0000 = g_Weapons (el resultado) Recordemos, que estamos utilizando Or(o)para la operación anterior que fijará cada posición de bit a 1 si existe en alguno de los operadores. Esta es la razón por g_Weapons ahora tiene cada bit en la posición apropiada de bits. Ahora que tenemos un campo de bits con nuestras armas deseadas, podemos comprobar el bit del arma con lo siguiente e.e: Código PHP: if ( g_Weapons & ( 1 << CSW_AWP ) ) Lo que está ocurriendo con esta afirmación es que estamos tomando y empujando el bit hacia la izquierda por CSW_AWP [18]bits. Esto establecerá el bit 18 a 1, de modo que será capaz de cotejarla con g_Weapons para ver si ambos bits existen en la posicion. Recordemos que el operador & comprueba si el bit es 1 en ambas posiciones de bit correspondiente en cada operando. 0000 0000 0000 0000 0000 0000 0000 0001 = 1 (numero 1 representado en bits hahaha) 0000 0000 0000 0100 0000 0000 0000 0000 = 1 << CSW_AWP (desplamamiento a la izquierda de 18 bits) 0000 0001 0000 0100 0010 0000 0000 0000 = g_Weapons 0000 0000 0000 0100 0000 0000 0000 0000 = Los bits en CSW_AWP [18] existen por la que deberian devolver true. Supongamos que queremos comprobar si la scout está en nuestro campo de bits. CSW_SCOUT = index 3. Código PHP: if ( g_Weapons & ( 1 << CSW_SCOUT ) ) 0000 0000 0000 0000 0000 0000 0000 0001 = 1 0000 0000 0000 0000 0000 0000 0000 1000 = 1 << CSW_SCOUT (desplazamiento a la izquierda de 3 bits) 0000 0001 0000 0100 0010 0000 0000 0000 = g_Weapons 0000 0000 0000 0000 0000 0000 0000 0000 = Bits en el cuarto bit la posicion (1<<3) devuelve false Ejemplo 3, utilizando un campo de bits para los plugins con flags\opciones. Código PHP: #define MAX_PLAYERS 32 Si usted va a hacer todo lo anterior con un array-bool necesitara crear un array de dos dimenciones como se demuestra a continuacion: Código PHP: #define MAX_PLAYERS 32 Macros utiles Para manipular fácilmente los bits en su plugin para trabajar con los jugadores (o algún de los 1-32 index) sin tener que volver a escribir las operaciones de bit cada vez, aquí hay algunas macros. Recuerde, el bit maximo que se puede manipular es de 32 en AMX-X ya que el único tipo de datos disponibles es una celda 4-byte [32 bits]. Código PHP: //Si va a almacenar un index de un jugador o cualquier cosa que tenga un index de hasta 32. Los beneficios del uso de campos de bits Una ventaja importante es conservar la memoria y la CPU, en la mayoría de los casos, más fácil que usar una gran variedad de Bools. Como se vio a principios de este tutorial, se ahorra 131 bytes de memoria mediante el uso de un campo de bits a través de un array, para almacenar valores bools(true o false) de un jugador e.e, tambien nos ahorramos codigo porque nostotros podemos comprobar rápidamente si los bits existen o no con una simple condicion(el if), utilizando un array que se necesita para algún tipo de loop para comprobar cada elemento. Manipulación de los bits fuera del rango de bits de una celda de memoria Esto se puede hacer mediante el uso de una array de bits. Esto simplemente utilizará el primer elemento del array para los bits 1-32, el segundo elemento para los bits 33-64, y así sucesivamente. No hay limitación maximo de bits en un array de bits. Código PHP: g_BitField[0] //bits 1-32 He aquí un ejemplo de cómo configurar el plugin para trabajar con bits ilimitados: Código PHP: #define SetBit(%1,%2) (%1[%2>>5] |= (1<<(%2 & 31))) Código PHP: //establecemos el bit mas alto que nosotros necesitamos para acceder Experimentando con numeros binarios Pawn tiene una constante (0b) tque le permite trabajar con valores en binario directamente. Para usarlo, preceda(como un prefix) un conjunto de bits con 0b, el número 10 en bits es representado por 1010 para almacenar este valor en una variable, se haría ivar = 0b1010. Esto funciona de forma idéntica al prefijo 0x hexadecimal que usted pudo haber visto utilizado en otros lugares. unos 5 ejemplos Código PHP: i1 = 0b1; ejemplo de una operacion e.e: Código PHP: new iNum1 = 0b1011; //11 aca dejo unos stocks que me paso gladius: Código PHP: stock Decimal_To_Binario(input_num, output_sznum[], output_size) Código PHP: stock Numero_Par(num) Tip: Comparar bits como booleans.(Mario AR) Mario AR. escribió:Aquí nos vamos a valer del operador !. Sabemos que los booleans almacenan 2 valores: 0 (falso) y 1 (verdadero). Si utilizamos un bit de una variable como un boolean, al hacer una operación para comprobar si este bit está seteado en 1 (verdadero) no siempre obtendremos como resultado 1. Aquí la demostración: RE: Bitsums - alan_el_more - 08/10/2013 Hoy estuve leyendo el post original y no entendía varias partes, gracias por traducirlo y compartirlo RE: Bitsums - roccoxx - 08/10/2013 (08/10/2013, 12:58 PM)alan_el_more escribió: Hoy estuve leyendo el post original y no entendía varias partes, gracias por traducirlo y compartirlo denada, ahora subo unos stocks que me paso gladius :3 RE: Bitsums - gladius - 08/10/2013 Si es una traducción por lo visto. Eres capaz de darle soporte si a alguien el surge alguna duda? RE: Bitsums - roccoxx - 08/10/2013 Si gladius RE: Bitsums - cr1st - 19/10/2013 tengo una pequeña duda y nose si es posible teniendo en cuenta esto Código PHP: #define ADMIN_LEVEL_H (1<<19) /* flag "t" */ se podria crear una define nueva con la suma de estas dos??? intente de varias maneras pero no pudre Código PHP: #define USER_VIP (1<<(19&25)) edit: tmb encontre esto Código PHP: #define ADMIN_LEVEL_H 524288 //Flag "t", custom sume los dos Código PHP: #define USER_VIP 34078720 pero a los users normales tmb se los toma. asi q no va gracias de antemano RE: Bitsums - alan_el_more - 19/10/2013 Código PHP: #define USER_VIP (1<<19)|(1<<25) RE: Bitsums - gladius - 19/10/2013 Este operador no sé por qué no lo usan ~ (Not) y eso que está explicado pero no lo he visto en ningún plugin de Spanish al menos. por ejemplo Código PHP: if(~get_user_flags(id) & ADMIN_BAN) RE: Bitsums - alan_el_more - 19/10/2013 (19/10/2013, 03:02 PM)gladius escribió: Este operador no sé por qué no lo usan ~ (Not) y eso que está explicado pero no lo he visto en ningún plugin de Spanish al menos. No de esa forma pero si se usa RE: Bitsums - cr1st - 19/10/2013 (19/10/2013, 12:41 PM)alan_el_more escribió: muchas gracias por la respuesta pero esta forma no me sirvio... me toma el player como vip se me ocurrio probar esta y quedo joya Código PHP: #define USER_VIP (1<<19^25) RE: Bitsums - gladius - 19/10/2013 Qe quieres hacer realmente, porque si colocas el 1<<25 te va a tomar a todos los jugadores ya que esa flag es para todos. Si quieres solo admin de algo usa alguna de las flag pero que no sea ADMIN_USER. RE: Bitsums - alan_el_more - 26/10/2013 Una información muy útil y un stock por si queres usar 32 flags, ya que el amxx por defecto trae 25 (de la 'a' a la 'z') Código: #1 33 read_flags("!") == 1 | 1<<0 == 1 Código PHP: #define get_flags UTIL_GetFlags Estaría bueno que lo agregues al post principal RE: Bitsums - Mía - 14/05/2014 No sería más fácil.. Código PHP: #define SetPlayerBit(%1,%2) (%1 |= (1<<(%2&31))) Código PHP: #define SetPlayerBit(%1, %2) (%1 |= (1<<(%2-1))) RE: Bitsums - Neeeeeeeeeel.- - 14/05/2014 (14/05/2014, 08:24 AM)Mario AR. escribió: No sería más fácil..Es un macro... no necesitás entenderlo cada vez que lo vas a usar, lo que tenés que saber es lo que hace el macro completo. RE: Bitsums - wicho - 18/02/2015 Tengo una pregunta como puedo hacer esto g_variable[id]++ con un bit? RE: Bitsums - Milashkasiya - 18/02/2015 (18/02/2015, 05:16 AM)wicho escribió: Tengo una pregunta como puedo hacer esto g_variable[id]++ con un bit? No puedes. RE: Bitsums - Neeeeeeeeeel.- - 18/02/2015 (18/02/2015, 05:16 AM)wicho escribió: Tengo una pregunta como puedo hacer esto g_variable[id]++ con un bit? Un bit es 1 o 0, solo podés cambiarlo de estado... no tiene sentido un "++". RE: Bitsums - Mía - 20/02/2015 (18/02/2015, 05:16 AM)wicho escribió: Tengo una pregunta como puedo hacer esto g_variable[id]++ con un bit? Puedes cambiarlo de 0 a 1 y viceversa con el operador XOR: Código PHP: intercambiar_bit(variable, id) RE: Bitsums - wicho - 21/02/2015 gracias, bueno era para usarlo como bool es que le estaba poniendo limite a un extra item de zombie y tenia duda de si habia forma de hacerlo con bitsums.. RE: Bitsums - mongito100 - 21/02/2015 (21/02/2015, 01:29 AM)wicho escribió: gracias, bueno era para usarlo como bool es que le estaba poniendo limite a un extra item de zombie y tenia duda de si habia forma de hacerlo con bitsums.. si quieres optimisar en el sentido de usar menos memoria puedes usar {} suponiendo q necesites 4 variables parecidas q vayan del 0 al 255 para mas info mira el tut de destro RE: Bitsums - sasske - 21/02/2015 (21/02/2015, 01:29 AM)wicho escribió: gracias, bueno era para usarlo como bool es que le estaba poniendo limite a un extra item de zombie y tenia duda de si habia forma de hacerlo con bitsums.. los bool son verdadero o falso, osea, son 1 o 0 RE: Bitsums - I'mBuggimen - 21/11/2015 he estado leyendo esto y he comprendido varias cosas y muchas dudas aclaradas pero aun no me queda claro el operador % que hace ? cuando habría que usarlo ? RE: Bitsums - Heber[$]ource - 21/11/2015 (21/11/2015, 05:25 PM)ImBuggimen escribió: he estado leyendo esto y he comprendido varias cosas y muchas dudas aclaradas pero En todo el tutorial solo eh visto ese operador en las macros y en el stock de gladius (para convertir numeros decimales a binarios). Ese operador lo que hace es calcular el resto de una division. Ejemplo: Código PHP: public plugin_init() RE: Bitsums - I'mBuggimen - 21/11/2015 bueno me quedo claro ya muchas gracias |