diff --git a/css/lightbox.css b/css/lightbox.css
new file mode 100644
index 0000000..e55b2d0
--- /dev/null
+++ b/css/lightbox.css
@@ -0,0 +1,27 @@
+#lightbox{ position: absolute; left: 0; width: 100%; z-index: 100; text-align: center; line-height: 0;}
+#lightbox img{ width: auto; height: auto;}
+#lightbox a img{ border: none; }
+
+#outerImageContainer{ position: relative; background-color: #fff; width: 250px; height: 250px; margin: 0 auto; }
+#imageContainer{ padding: 10px; }
+
+#loading{ position: absolute; top: 40%; left: 0%; height: 25%; width: 100%; text-align: center; line-height: 0; }
+#hoverNav{ position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 10; }
+#imageContainer>#hoverNav{ left: 0;}
+#hoverNav a{ outline: none;}
+
+#prevLink, #nextLink{ width: 49%; height: 100%; background-image: url(data:image/gif;base64,AAAA); /* Trick IE into showing hover */ display: block; }
+#prevLink { left: 0; float: left;}
+#nextLink { right: 0; float: right;}
+#prevLink:hover, #prevLink:visited:hover { background: url(../images/prevlabel.gif) left 15% no-repeat; }
+#nextLink:hover, #nextLink:visited:hover { background: url(../images/nextlabel.gif) right 15% no-repeat; }
+
+#imageDataContainer{ font: 10px Verdana, Helvetica, sans-serif; background-color: #fff; margin: 0 auto; line-height: 1.4em; overflow: auto; width: 100% ; }
+
+#imageData{ padding:0 10px; color: #666; }
+#imageData #imageDetails{ width: 70%; float: left; text-align: left; }
+#imageData #caption{ font-weight: bold; }
+#imageData #numberDisplay{ display: block; clear: left; padding-bottom: 1.0em; }
+#imageData #bottomNavClose{ width: 66px; float: right; padding-bottom: 0.7em; outline: none;}
+
+#overlay{ position: absolute; top: 0; left: 0; z-index: 90; width: 100%; height: 500px; background-color: #000; }
diff --git a/estilos.css b/estilos.css
new file mode 100644
index 0000000..61d45b3
--- /dev/null
+++ b/estilos.css
@@ -0,0 +1,338 @@
+html, body {
+ text-align:center;
+ background-color: #F1F1F1;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ background-image: url('images/back.gif');
+ background-repeat: repeat-y;
+ background-position: center;
+ margin:0;
+ padding:0;
+}
+
+
+a {
+ color: #FF6600;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+a:visited {
+ color: #FF6600;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #0066CC;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+a:active {
+ color: #082C63;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+hr {
+ color: #FA6F05;
+ background-color: #FA6F05;
+ height: 1px;
+ padding: 0;
+ border: 0px;
+}
+
+h1 {
+ padding-top: 2px;
+ margin:0 0 0 10px;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 34px;
+ color: #FFF0F9;
+}
+
+h2 {
+ margin: 10px 0px 10px 10px;
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
+ font-size: 16px;
+ color: #FF6600;
+}
+
+h3 {
+ margin: 10px 0px 10px 10px;
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
+ color: #FF6600;
+ font-size: 14px;
+}
+
+p, ul {
+ color: #666666;
+ line-height: 18px;
+ margin: 0;
+ padding: 0;
+}
+
+#pagewidth{
+ margin:0;
+ padding:0;
+ width:780px;
+ text-align:left;
+ min-width: 500px;
+ margin-left:auto;
+ margin-right:auto;
+}
+html>body #pagewidth {
+ width: 780px;
+}
+
+#header{
+ height:100px;
+ background-color:#FA6F05;
+ margin: 0;
+ padding: 0;
+ background-image: url('images/header.jpg');
+ background-repeat: no-repeat;
+}
+
+#header h2 {
+ font-family: Arial, Helvetica, sans-serif;
+ color: #FFE0C9;
+ font-size:20px;
+ font-weight: normal;
+ margin: -5px 0px 15px 10px;
+}
+
+#header h3 {
+ color: #FFF6EF;
+ font-size:14px;
+ font-weight: bold;
+ margin: 0px 0px 0px 10px;
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+#header h4 {
+ font-family: Arial, Helvetica, sans-serif;
+ color: #FFFFFF;
+ font-size:14px;
+ font-weight: bold;
+ margin: -15px 0px 15px 10px;
+}
+
+#header a {
+ color: #FAECD9;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+#header a:hover {
+ color: #0066CC;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+#header a:active {
+ color: #082C63;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+
+#footer {
+ background-color:#FA6F05;
+ margin: 0;
+ padding: 5px 10px;
+ background-image: url('images/header.jpg');
+ background-repeat: no-repeat;
+ background-position: 0px -20px;
+}
+
+#footer p{
+ color: #FFE0C9;
+}
+
+#footer a {
+ color: #FAECD9;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+#footer a:hover {
+ color: #0066CC;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+#footer a:active {
+ color: #082C63;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+
+#outer{
+ background-color: #FFFFFF; /* center column colour */
+ width: auto;
+ }
+
+#inner{margin:0; width:100%;}
+
+#maincol{
+ float: left;
+ width: 100%;
+ position: relative;
+ margin: 0 -8px 0 -2px;
+ background-color: #FFFFFF;
+ }
+
+.clr{clear:both;}
+
+.content{padding:0px;margin:0px;} /*padding for content */
+
+#header .content{padding-bottom:0;} /*padding bottom 0 to remove space in IE5 Mac*/
+
+.seccion {
+ width: 100%;
+ padding: 0;
+ padding: 0px 0 20px 0;
+ border: 1px solid #FFFFFF;
+ background-color: #F1EFE2;
+}
+
+.texto {
+ float: left;
+ width: 162px;
+ padding: 0px 15px 0px 15px;
+}
+
+ul.caracteristicas {
+ float: left;
+ border-left: 30px solid #F1EFE2;
+}
+
+ul.caracteristicas li {
+ list-style-type: square;
+ list-style-position: outside;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+
+.foto, .foto2 {
+ float: right;
+ width: auto;
+ min-width: 195px;
+ text-align: center;
+ position: relative;
+}
+
+.foto img, .foto2 img {
+ margin: 0px 3px;
+ padding: 0;
+ border: 1px solid #ACA899;
+}
+
+.foto2 {
+ padding-right: 30px;
+}
+
+.novedad {
+ float: right;
+ font-size: 10px;
+ font-weight: bold;
+ background-color: #FA6F05;
+ position: absolute;
+ right: 0;
+ top: -3px;
+ padding: 3px 5px;
+ color: #FFF;
+ border-left: 1px solid #6A2B00;
+ border-bottom: 1px solid #6A2B00;
+}
+
+.piefoto {
+ padding: 0px 8px;
+ margin: 0px 3px;
+ text-align: center;
+ font-size: 11px;
+ line-height: normal;
+ background-color: #FFFFFF;
+}
+
+.nombre {
+ float:left;
+ margin: 10px 0 0 0;
+}
+
+.direccion {
+ float: right;
+ width: 244px;
+ margin: 15px 5px 0 0;
+ text-align: right;
+}
+
+.horario {
+ float: right;
+ width: 232px;
+ text-align: right;
+ background-color:#FFF6EF;
+ padding: 0px 10px 0px 0px;
+ margin: 3px 0px 0px 0px;
+}
+
+.horario p {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ margin: 0px 0px 5px 0px;
+}
+
+.horario h2 {
+ margin: 10px 0px 5px 5px;
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ color: #FF6600;
+}
+
+.otrapagina {
+ background-color:#FA6F05;
+ margin: 0;
+ padding: 0;
+ background-image: url('images/back_banner.gif');
+ padding: 10px 0px 10px 10px;
+ border-top: 3px solid #ffffff;
+ border-bottom: 3px solid #ffffff;
+ background-color: #F1F1F1;
+ float:left;
+ width: 525px;
+}
+
+.otrapagina p {
+ font-size: 18px;
+ font-weight: normal;
+ line-height: 120%;
+ color: #0064C4;
+}
+
+.otrapagina a {
+ color: #0063C1;
+ font-size: 26px;
+ font-weight: bold;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+.otrapagina a:visited {
+ color: #0066CC;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+.otrapagina a:hover {
+ color: #0B87FF;
+ border-bottom: none;
+ text-decoration: none;
+}
+
+.otrapagina a:active {
+ color: #0066CC;
+ border-bottom: none;
+ text-decoration: none;
+}
diff --git a/favicon.ico b/favicon.ico
new file mode 100644
index 0000000..271a7df
Binary files /dev/null and b/favicon.ico differ
diff --git a/galeria.htm b/galeria.htm
new file mode 100644
index 0000000..10be319
--- /dev/null
+++ b/galeria.htm
@@ -0,0 +1,263 @@
+
+
+
+
+PINCEL CRISTAL - Mamparas de baño y puertas de cristal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Visite nuestra página www.reforma50metros.com Descubra las ventajas del cristal en su hogar mediante puertas de bisagra o correderas, mamparas de baño, paneles o tabiques , ganando luminosidad y espacio en su casa
+
+
+
Horario de atención al público
+
Teléfono. 9:30 a 20:30 Taller. 12:00 a 14:00 y 18:00 a 20:00 Viernes tarde y sabado cerrado Concertar cita para visita a taller
+
+
+
+
+
+
+
+
Galería de montaje - Puerta corredera de cristal
+
Los diseños de nuestras puertas de cristal son totalmente personalizables, al igual que los herrajes y vinilos.< Volver a la página principal
+
+
+
+
+
+
+
+
+
Galería de montaje - Puerta corredera de cristal de diseño
+
Puesta corredera con tapa de aluminio plata mate. Montaje especial con cristal de medio punto. Los diseños de nuestras puertas de cristal son totalmente personalizables.< Volver a la página principal
+
+
+
+
+
+
+
+
+
Galería de montaje - Puerta corredera de doble hoja
+
Los diseños de nuestras puertas de cristal son totalmente personalizables, al igual que los herrajes y vinilos, aportan transparencia y claridad.< Volver a la página principal
+
+
+
+
+
+
+
+
Galería de montaje - Puerta con sistema aereo de acero
+
Nuestro sistema aereo Concept de acero inox, puede fabricarse en cualquier medida.< Volver a la página principal
+
+
+
+
+
+
+
+
+
+
+
Galería de montaje - Puerta corredera de aluminio
+
Puerta corredera de aluminio adaptada a un hueco de 80 cm x 2,10cm dew altura con vidreo de seguridad vinilo de cuadraditos< Volver a la página principal
+
+
+
+
+
+
+
Galería de montaje - Puerta corredera para cocina
+
Nuestras puertas corredera son a medida y sin necesidad de obra< Volver a la página principal
+
+
+
+
+
+
+
Galería de montaje - Puertas de corredera de cristal a medida
+
Nuestras puertas de cristal de corredera, son a medida, sin necesidad de obra.< Volver a la página principal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Galería de montaje - Comercio con puertas de cristal
+
Nuestro sistema aereo Concept de acero inox, puede fabricarse en cualquier medida.< Volver a la página principal
+
+
+
+
+
+
+
+
+
Galería de montaje - Pared de cristal a medida
+
Nuestros paneles, tabiques o paredes de cristal, perimiten tener luminosidad en todos los rincones de su hogar, son totalmente a medida y no es necesaria obra.< Volver a la página principal
+
+
+
+
+
+
+
+
+
+
+
Galería de montaje - Mamparas de cristal para baños
+
Se realizó la sustitución de la bañera por un plato de ducha rectangular. Mediante el cristal de pavés se aportó más luminosidad al baño. Para cubrir la parte inferior de la pared ocupada por la bañera se utilizaron azulejos.< Volver a la página principal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/galeria/b1.jpg b/galeria/b1.jpg
new file mode 100644
index 0000000..9e58654
Binary files /dev/null and b/galeria/b1.jpg differ
diff --git a/galeria/b2.jpg b/galeria/b2.jpg
new file mode 100644
index 0000000..1f236e3
Binary files /dev/null and b/galeria/b2.jpg differ
diff --git a/galeria/b3.jpg b/galeria/b3.jpg
new file mode 100644
index 0000000..019b71f
Binary files /dev/null and b/galeria/b3.jpg differ
diff --git a/galeria/b4.jpg b/galeria/b4.jpg
new file mode 100644
index 0000000..d5cb391
Binary files /dev/null and b/galeria/b4.jpg differ
diff --git a/galeria/big/Thumbs.db b/galeria/big/Thumbs.db
new file mode 100644
index 0000000..f8cb9fc
Binary files /dev/null and b/galeria/big/Thumbs.db differ
diff --git a/galeria/big/b1.jpg b/galeria/big/b1.jpg
new file mode 100644
index 0000000..556b7ab
Binary files /dev/null and b/galeria/big/b1.jpg differ
diff --git a/galeria/big/b2.jpg b/galeria/big/b2.jpg
new file mode 100644
index 0000000..cf692eb
Binary files /dev/null and b/galeria/big/b2.jpg differ
diff --git a/galeria/big/b3.jpg b/galeria/big/b3.jpg
new file mode 100644
index 0000000..01c9ab0
Binary files /dev/null and b/galeria/big/b3.jpg differ
diff --git a/galeria/big/b4.jpg b/galeria/big/b4.jpg
new file mode 100644
index 0000000..be12358
Binary files /dev/null and b/galeria/big/b4.jpg differ
diff --git a/galeria/big/comercios1.jpg b/galeria/big/comercios1.jpg
new file mode 100644
index 0000000..31d7045
Binary files /dev/null and b/galeria/big/comercios1.jpg differ
diff --git a/galeria/big/comercios2.jpg b/galeria/big/comercios2.jpg
new file mode 100644
index 0000000..90ddcff
Binary files /dev/null and b/galeria/big/comercios2.jpg differ
diff --git a/galeria/big/comercios3.jpg b/galeria/big/comercios3.jpg
new file mode 100644
index 0000000..5983833
Binary files /dev/null and b/galeria/big/comercios3.jpg differ
diff --git a/galeria/big/comercios4.jpg b/galeria/big/comercios4.jpg
new file mode 100644
index 0000000..4975ff6
Binary files /dev/null and b/galeria/big/comercios4.jpg differ
diff --git a/galeria/big/mpc02.jpg b/galeria/big/mpc02.jpg
new file mode 100644
index 0000000..703b41a
Binary files /dev/null and b/galeria/big/mpc02.jpg differ
diff --git a/galeria/big/mpc03.jpg b/galeria/big/mpc03.jpg
new file mode 100644
index 0000000..8c22926
Binary files /dev/null and b/galeria/big/mpc03.jpg differ
diff --git a/galeria/big/mpc04.jpg b/galeria/big/mpc04.jpg
new file mode 100644
index 0000000..9c0441c
Binary files /dev/null and b/galeria/big/mpc04.jpg differ
diff --git a/galeria/big/mpc05.jpg b/galeria/big/mpc05.jpg
new file mode 100644
index 0000000..cc7d545
Binary files /dev/null and b/galeria/big/mpc05.jpg differ
diff --git a/galeria/big/mpc101.jpg b/galeria/big/mpc101.jpg
new file mode 100644
index 0000000..68376d6
Binary files /dev/null and b/galeria/big/mpc101.jpg differ
diff --git a/galeria/big/mpc102.jpg b/galeria/big/mpc102.jpg
new file mode 100644
index 0000000..73be738
Binary files /dev/null and b/galeria/big/mpc102.jpg differ
diff --git a/galeria/big/mpc103.jpg b/galeria/big/mpc103.jpg
new file mode 100644
index 0000000..738e5d0
Binary files /dev/null and b/galeria/big/mpc103.jpg differ
diff --git a/galeria/big/p1.jpg b/galeria/big/p1.jpg
new file mode 100644
index 0000000..905f016
Binary files /dev/null and b/galeria/big/p1.jpg differ
diff --git a/galeria/big/p2.jpg b/galeria/big/p2.jpg
new file mode 100644
index 0000000..2041ecf
Binary files /dev/null and b/galeria/big/p2.jpg differ
diff --git a/galeria/big/p3.jpg b/galeria/big/p3.jpg
new file mode 100644
index 0000000..18ac32d
Binary files /dev/null and b/galeria/big/p3.jpg differ
diff --git a/galeria/big/p4.jpg b/galeria/big/p4.jpg
new file mode 100644
index 0000000..2b3e02a
Binary files /dev/null and b/galeria/big/p4.jpg differ
diff --git a/galeria/big/puertac1m4.jpg b/galeria/big/puertac1m4.jpg
new file mode 100644
index 0000000..4acf38e
Binary files /dev/null and b/galeria/big/puertac1m4.jpg differ
diff --git a/galeria/big/puertac1m42.jpg b/galeria/big/puertac1m42.jpg
new file mode 100644
index 0000000..0868df0
Binary files /dev/null and b/galeria/big/puertac1m42.jpg differ
diff --git a/galeria/big/puertac1m5.jpg b/galeria/big/puertac1m5.jpg
new file mode 100644
index 0000000..e161086
Binary files /dev/null and b/galeria/big/puertac1m5.jpg differ
diff --git a/galeria/big/puertac1m52.jpg b/galeria/big/puertac1m52.jpg
new file mode 100644
index 0000000..214c2f5
Binary files /dev/null and b/galeria/big/puertac1m52.jpg differ
diff --git a/galeria/big/puertac1m6.jpg b/galeria/big/puertac1m6.jpg
new file mode 100644
index 0000000..46b9e03
Binary files /dev/null and b/galeria/big/puertac1m6.jpg differ
diff --git a/galeria/big/puertac1m62.jpg b/galeria/big/puertac1m62.jpg
new file mode 100644
index 0000000..029ea55
Binary files /dev/null and b/galeria/big/puertac1m62.jpg differ
diff --git a/galeria/bisagras.jpg b/galeria/bisagras.jpg
new file mode 100644
index 0000000..a8d9645
Binary files /dev/null and b/galeria/bisagras.jpg differ
diff --git a/galeria/bisagras2.jpg b/galeria/bisagras2.jpg
new file mode 100644
index 0000000..3fc1292
Binary files /dev/null and b/galeria/bisagras2.jpg differ
diff --git a/galeria/comercios1.jpg b/galeria/comercios1.jpg
new file mode 100644
index 0000000..47e94ec
Binary files /dev/null and b/galeria/comercios1.jpg differ
diff --git a/galeria/comercios2.jpg b/galeria/comercios2.jpg
new file mode 100644
index 0000000..32a798e
Binary files /dev/null and b/galeria/comercios2.jpg differ
diff --git a/galeria/comercios3.jpg b/galeria/comercios3.jpg
new file mode 100644
index 0000000..4ead025
Binary files /dev/null and b/galeria/comercios3.jpg differ
diff --git a/galeria/comercios4.jpg b/galeria/comercios4.jpg
new file mode 100644
index 0000000..babaccd
Binary files /dev/null and b/galeria/comercios4.jpg differ
diff --git a/galeria/herrajes.jpg b/galeria/herrajes.jpg
new file mode 100644
index 0000000..6d152a0
Binary files /dev/null and b/galeria/herrajes.jpg differ
diff --git a/galeria/herrajes1.jpg b/galeria/herrajes1.jpg
new file mode 100644
index 0000000..7421d02
Binary files /dev/null and b/galeria/herrajes1.jpg differ
diff --git a/galeria/herrajes2.jpg b/galeria/herrajes2.jpg
new file mode 100644
index 0000000..dbc5c60
Binary files /dev/null and b/galeria/herrajes2.jpg differ
diff --git a/galeria/mpc01.jpg b/galeria/mpc01.jpg
new file mode 100644
index 0000000..cf838d0
Binary files /dev/null and b/galeria/mpc01.jpg differ
diff --git a/galeria/mpc02.jpg b/galeria/mpc02.jpg
new file mode 100644
index 0000000..5491873
Binary files /dev/null and b/galeria/mpc02.jpg differ
diff --git a/galeria/mpc03.jpg b/galeria/mpc03.jpg
new file mode 100644
index 0000000..6168ac3
Binary files /dev/null and b/galeria/mpc03.jpg differ
diff --git a/galeria/mpc04.jpg b/galeria/mpc04.jpg
new file mode 100644
index 0000000..044007d
Binary files /dev/null and b/galeria/mpc04.jpg differ
diff --git a/galeria/mpc05.jpg b/galeria/mpc05.jpg
new file mode 100644
index 0000000..774a2d8
Binary files /dev/null and b/galeria/mpc05.jpg differ
diff --git a/galeria/mpc06.jpg b/galeria/mpc06.jpg
new file mode 100644
index 0000000..dea3258
Binary files /dev/null and b/galeria/mpc06.jpg differ
diff --git a/galeria/mpc101.jpg b/galeria/mpc101.jpg
new file mode 100644
index 0000000..16abe0e
Binary files /dev/null and b/galeria/mpc101.jpg differ
diff --git a/galeria/mpc102.jpg b/galeria/mpc102.jpg
new file mode 100644
index 0000000..3aabf08
Binary files /dev/null and b/galeria/mpc102.jpg differ
diff --git a/galeria/mpc103.jpg b/galeria/mpc103.jpg
new file mode 100644
index 0000000..e1142c6
Binary files /dev/null and b/galeria/mpc103.jpg differ
diff --git a/galeria/p1.jpg b/galeria/p1.jpg
new file mode 100644
index 0000000..0eea0e8
Binary files /dev/null and b/galeria/p1.jpg differ
diff --git a/galeria/p2.jpg b/galeria/p2.jpg
new file mode 100644
index 0000000..91541fe
Binary files /dev/null and b/galeria/p2.jpg differ
diff --git a/galeria/p3.jpg b/galeria/p3.jpg
new file mode 100644
index 0000000..b3c6e7c
Binary files /dev/null and b/galeria/p3.jpg differ
diff --git a/galeria/p4.jpg b/galeria/p4.jpg
new file mode 100644
index 0000000..71ba2a6
Binary files /dev/null and b/galeria/p4.jpg differ
diff --git a/galeria/pinzas.jpg b/galeria/pinzas.jpg
new file mode 100644
index 0000000..b5a0650
Binary files /dev/null and b/galeria/pinzas.jpg differ
diff --git a/galeria/puertac1m1.jpg b/galeria/puertac1m1.jpg
new file mode 100644
index 0000000..77e4372
Binary files /dev/null and b/galeria/puertac1m1.jpg differ
diff --git a/galeria/puertac1m2.jpg b/galeria/puertac1m2.jpg
new file mode 100644
index 0000000..3c403a3
Binary files /dev/null and b/galeria/puertac1m2.jpg differ
diff --git a/galeria/puertac1m3.jpg b/galeria/puertac1m3.jpg
new file mode 100644
index 0000000..6db8bc8
Binary files /dev/null and b/galeria/puertac1m3.jpg differ
diff --git a/galeria/puertac1m4.jpg b/galeria/puertac1m4.jpg
new file mode 100644
index 0000000..4d38dea
Binary files /dev/null and b/galeria/puertac1m4.jpg differ
diff --git a/galeria/puertac1m42.jpg b/galeria/puertac1m42.jpg
new file mode 100644
index 0000000..34fa30d
Binary files /dev/null and b/galeria/puertac1m42.jpg differ
diff --git a/galeria/puertac1m5.jpg b/galeria/puertac1m5.jpg
new file mode 100644
index 0000000..d4fdc85
Binary files /dev/null and b/galeria/puertac1m5.jpg differ
diff --git a/galeria/puertac1m52.jpg b/galeria/puertac1m52.jpg
new file mode 100644
index 0000000..7607031
Binary files /dev/null and b/galeria/puertac1m52.jpg differ
diff --git a/galeria/puertac1m6.jpg b/galeria/puertac1m6.jpg
new file mode 100644
index 0000000..715db8a
Binary files /dev/null and b/galeria/puertac1m6.jpg differ
diff --git a/galeria/puertac1m62.jpg b/galeria/puertac1m62.jpg
new file mode 100644
index 0000000..e6705c7
Binary files /dev/null and b/galeria/puertac1m62.jpg differ
diff --git a/galeria/tabique1m1.jpg b/galeria/tabique1m1.jpg
new file mode 100644
index 0000000..530e647
Binary files /dev/null and b/galeria/tabique1m1.jpg differ
diff --git a/galeria/tabique1m2.jpg b/galeria/tabique1m2.jpg
new file mode 100644
index 0000000..b5d913e
Binary files /dev/null and b/galeria/tabique1m2.jpg differ
diff --git a/galeria/tabique1m3.jpg b/galeria/tabique1m3.jpg
new file mode 100644
index 0000000..8d9dc69
Binary files /dev/null and b/galeria/tabique1m3.jpg differ
diff --git a/herrajes.htm b/herrajes.htm
new file mode 100644
index 0000000..c4eed20
--- /dev/null
+++ b/herrajes.htm
@@ -0,0 +1,85 @@
+
+
+
+
+PINCEL CRISTAL - Mamparas de baño y puertas de cristal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Visite nuestra página www.reforma50metros.com Descubra las ventajas del cristal en su hogar mediante puertas de bisagra o correderas, mamparas de baño, paneles o tabiques , ganando luminosidad y espacio en su casa
+
+
+
Horario de atención al público
+
Teléfono. 9:30 a 20:30 Taller. 12:00 a 14:00 y 18:00 a 20:00 Viernes tarde y sabado cerrado Concertar cita para visita a taller
+
+
+
+
+
+
+
+
Galería de herrajes
+
Automatismos, herrajes y accesorios para puertas correderas, puertas de bisagra, tabiques y paneles, todas ellas de cristal. Diferentes acabados disponibles, realizados en acero inoxidable para su uso en contacto con el agua: cromado brillante, cromado mate, acero inoxidable... < Volver a la página principal
+
+
+
Sistema de montaje modelo DAVINES en terminación aluminio mate
+
+
+
+
+
+
Automatismos y herrajes CONCEPT en ACERO INOX para puertas de corredera
+
+
+
+
+
+
Herrajes para puertas interiores de corredera y de bisagra, cerraduras y barras de refuerzo
+
+
+
+
+
+
Bisagras y tiradores
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/images/back.gif b/images/back.gif
new file mode 100644
index 0000000..b2e1761
Binary files /dev/null and b/images/back.gif differ
diff --git a/images/back_banner.gif b/images/back_banner.gif
new file mode 100644
index 0000000..598715d
Binary files /dev/null and b/images/back_banner.gif differ
diff --git a/images/big/comercios1.jpg b/images/big/comercios1.jpg
new file mode 100644
index 0000000..31d7045
Binary files /dev/null and b/images/big/comercios1.jpg differ
diff --git a/images/big/comercios2.jpg b/images/big/comercios2.jpg
new file mode 100644
index 0000000..90ddcff
Binary files /dev/null and b/images/big/comercios2.jpg differ
diff --git a/images/big/puerta1.jpg b/images/big/puerta1.jpg
new file mode 100644
index 0000000..ceb1d40
Binary files /dev/null and b/images/big/puerta1.jpg differ
diff --git a/images/big/puertac11.jpg b/images/big/puertac11.jpg
new file mode 100644
index 0000000..462bd09
Binary files /dev/null and b/images/big/puertac11.jpg differ
diff --git a/images/big/puertac22.jpg b/images/big/puertac22.jpg
new file mode 100644
index 0000000..0fa4943
Binary files /dev/null and b/images/big/puertac22.jpg differ
diff --git a/images/big/puertac3.jpg b/images/big/puertac3.jpg
new file mode 100644
index 0000000..537a3a5
Binary files /dev/null and b/images/big/puertac3.jpg differ
diff --git a/images/big/puertac33.jpg b/images/big/puertac33.jpg
new file mode 100644
index 0000000..214c2f5
Binary files /dev/null and b/images/big/puertac33.jpg differ
diff --git a/images/big/puertac5.jpg b/images/big/puertac5.jpg
new file mode 100644
index 0000000..cc7d545
Binary files /dev/null and b/images/big/puertac5.jpg differ
diff --git a/images/big/tabique2.jpg b/images/big/tabique2.jpg
new file mode 100644
index 0000000..c3e8ce2
Binary files /dev/null and b/images/big/tabique2.jpg differ
diff --git a/images/bullet.gif b/images/bullet.gif
new file mode 100644
index 0000000..bf8e3c6
Binary files /dev/null and b/images/bullet.gif differ
diff --git a/images/close.gif b/images/close.gif
new file mode 100644
index 0000000..ca517b6
Binary files /dev/null and b/images/close.gif differ
diff --git a/images/closelabel.gif b/images/closelabel.gif
new file mode 100644
index 0000000..87b4f8b
Binary files /dev/null and b/images/closelabel.gif differ
diff --git a/images/donate-button.gif b/images/donate-button.gif
new file mode 100644
index 0000000..78cfb77
Binary files /dev/null and b/images/donate-button.gif differ
diff --git a/images/download-icon.gif b/images/download-icon.gif
new file mode 100644
index 0000000..4987a2c
Binary files /dev/null and b/images/download-icon.gif differ
diff --git a/images/header.jpg b/images/header.jpg
new file mode 100644
index 0000000..83ca907
Binary files /dev/null and b/images/header.jpg differ
diff --git a/images/image-1.jpg b/images/image-1.jpg
new file mode 100644
index 0000000..1f8ab9f
Binary files /dev/null and b/images/image-1.jpg differ
diff --git a/images/loading.gif b/images/loading.gif
new file mode 100644
index 0000000..f864d5f
Binary files /dev/null and b/images/loading.gif differ
diff --git a/images/mampara1.jpg b/images/mampara1.jpg
new file mode 100644
index 0000000..9ca5ef0
Binary files /dev/null and b/images/mampara1.jpg differ
diff --git a/images/mampara2.jpg b/images/mampara2.jpg
new file mode 100644
index 0000000..546191f
Binary files /dev/null and b/images/mampara2.jpg differ
diff --git a/images/mampara3.jpg b/images/mampara3.jpg
new file mode 100644
index 0000000..149f19f
Binary files /dev/null and b/images/mampara3.jpg differ
diff --git a/images/muro1.jpg b/images/muro1.jpg
new file mode 100644
index 0000000..2a89f8c
Binary files /dev/null and b/images/muro1.jpg differ
diff --git a/images/muro2.jpg b/images/muro2.jpg
new file mode 100644
index 0000000..948170c
Binary files /dev/null and b/images/muro2.jpg differ
diff --git a/images/muro3.jpg b/images/muro3.jpg
new file mode 100644
index 0000000..86da7fd
Binary files /dev/null and b/images/muro3.jpg differ
diff --git a/images/nextlabel.gif b/images/nextlabel.gif
new file mode 100644
index 0000000..6c40e51
Binary files /dev/null and b/images/nextlabel.gif differ
diff --git a/images/planta.gif b/images/planta.gif
new file mode 100644
index 0000000..8a0bb6a
Binary files /dev/null and b/images/planta.gif differ
diff --git a/images/prevlabel.gif b/images/prevlabel.gif
new file mode 100644
index 0000000..51a31c2
Binary files /dev/null and b/images/prevlabel.gif differ
diff --git a/images/puerta1.jpg b/images/puerta1.jpg
new file mode 100644
index 0000000..239c79c
Binary files /dev/null and b/images/puerta1.jpg differ
diff --git a/images/puerta2.jpg b/images/puerta2.jpg
new file mode 100644
index 0000000..a5d4641
Binary files /dev/null and b/images/puerta2.jpg differ
diff --git a/images/puerta3.jpg b/images/puerta3.jpg
new file mode 100644
index 0000000..7f81282
Binary files /dev/null and b/images/puerta3.jpg differ
diff --git a/images/puerta4.jpg b/images/puerta4.jpg
new file mode 100644
index 0000000..3bf1036
Binary files /dev/null and b/images/puerta4.jpg differ
diff --git a/images/puertac1.jpg b/images/puertac1.jpg
new file mode 100644
index 0000000..77f3269
Binary files /dev/null and b/images/puertac1.jpg differ
diff --git a/images/puertac11.jpg b/images/puertac11.jpg
new file mode 100644
index 0000000..21431a3
Binary files /dev/null and b/images/puertac11.jpg differ
diff --git a/images/puertac2.jpg b/images/puertac2.jpg
new file mode 100644
index 0000000..fc2a3db
Binary files /dev/null and b/images/puertac2.jpg differ
diff --git a/images/puertac22.jpg b/images/puertac22.jpg
new file mode 100644
index 0000000..76d68fb
Binary files /dev/null and b/images/puertac22.jpg differ
diff --git a/images/puertac3.jpg b/images/puertac3.jpg
new file mode 100644
index 0000000..a3b1a49
Binary files /dev/null and b/images/puertac3.jpg differ
diff --git a/images/puertac33.jpg b/images/puertac33.jpg
new file mode 100644
index 0000000..a133f0b
Binary files /dev/null and b/images/puertac33.jpg differ
diff --git a/images/puertac4.jpg b/images/puertac4.jpg
new file mode 100644
index 0000000..7f71d75
Binary files /dev/null and b/images/puertac4.jpg differ
diff --git a/images/puertac5.jpg b/images/puertac5.jpg
new file mode 100644
index 0000000..a3739c4
Binary files /dev/null and b/images/puertac5.jpg differ
diff --git a/images/tabique1.jpg b/images/tabique1.jpg
new file mode 100644
index 0000000..9f3f920
Binary files /dev/null and b/images/tabique1.jpg differ
diff --git a/images/tabique2.jpg b/images/tabique2.jpg
new file mode 100644
index 0000000..445b06f
Binary files /dev/null and b/images/tabique2.jpg differ
diff --git a/images/tabique3.jpg b/images/tabique3.jpg
new file mode 100644
index 0000000..e388397
Binary files /dev/null and b/images/tabique3.jpg differ
diff --git a/images/thumb-1.jpg b/images/thumb-1.jpg
new file mode 100644
index 0000000..a598c80
Binary files /dev/null and b/images/thumb-1.jpg differ
diff --git a/images/toallero.jpg b/images/toallero.jpg
new file mode 100644
index 0000000..ad6009f
Binary files /dev/null and b/images/toallero.jpg differ
diff --git a/index.htm b/index.htm
new file mode 100644
index 0000000..ca60e79
--- /dev/null
+++ b/index.htm
@@ -0,0 +1,223 @@
+
+
+
+
+PINCEL CRISTAL - Mamparas de baño y puertas de cristal con bisagra o corredera
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Visite nuestra página www.reforma50metros.com Descubra las ventajas del cristal en su hogar mediante puertas de bisagra o correderas, mamparas de baño, paneles o tabiques , ganando luminosidad y espacio en su casa
+
+
+
Horario de atención al público
+
Teléfono. 9:30 a 20:30 Taller. 12:00 a 14:00 y 18:00 a 20:00 Viernes tarde y sabado cerrado Concertar cita para visita a taller
+
+
+
+
+
+
+
+
+
+
Montajes profesionales para comercios
+
En nuestros montajes para comercios utilizamos sistema concept acero inox fabricación propia , permiten un mejor aprovechamiento del espacio dando sensación de mayor amplitud, además de aportar belleza y luminosidad a su comercio.Ejemplo de montaje >
+
+
+
+
+
Clinica dental
+
+
+
+
+
+
Clinica dental
+
+
+
+
+
+
Mamparas de cristal para baños
+
Nuestras mamparas de baño son de fabricación propia utilizando cristal Securit. No utilizamos perfiles y la sujección se realizan mediante herrajes, dando sensación de profundidad además de transparencia y claridad a su baño.Ejemplo de montaje >
+
+
+
Angular de ducha con hoja abatible y 2 fijos
+
+
+
+
Frente de ducha de 2 abatibles y 2 fijos
+
+
+
+
Frente de baño de un fijo y una hoja abatible
+
+
+
+
+
+
Puertas de dos hojas abatibles y correderas, con cristal de diseño
+
Nuestras puertas son diseñadas para cada cliente.Ejemplo de montaje >
+
+
+
+
+
Puertas de vidrio con bisagras de acero inoxidable
+
+
+
+
Puertas de vidrio decorativas sujetas mediante bisagras
+
+
+
+
+
+
Puerta doble corredera de cristal templado terminación plata mate
+
+
+
+
+
+
Tabiques, paneles o paredes de cristal
+
Los paneles, tabiques y puertas de cristal permiten adecuar el espacio a sus necesidades, y todo sin necesidad de obra, quedando funcional y moderno .Ejemplo de montaje >
+
+
+
Distribución del baño con paneles de cristal
+
+
+
+
+
+
Ducha de obra incorporada en habitación con paneles de cristal
+
+
+
+
Tabique de vidrio para baño en cristal templado
+
+
+
+
+
+
Montajes sobre tabiques de obra
+
La diversidad de medidas y de situaciones hacen que la fabricación sea un proceso personalizado y adaptado a cada baño y con toma de medidas sobre el terreno.
+ Mampara de vidrio templado de 8mm (6mm si es puerta), bisagras abatibles para las hojas, permitiendo un mejor acceso a la ducha. Perfiles de goma coextrusionada para darle mayor estanqueidad, fácil limpieza y mantenimiento.
+
+
+
Mamparas sobre muretes de obra adaptadas al hueco
+
+
+
+
Cristal sobre murete
+
+
+
+
Murete de cristal y puerta abatible
+
+
+
+
+
+
Características principales
+
Galería de herrajes >
+
+
+
Sistema de montaje DAVINES en terminación aluminio plata mate
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/builder.js b/js/builder.js
new file mode 100644
index 0000000..d9731c9
--- /dev/null
+++ b/js/builder.js
@@ -0,0 +1,136 @@
+// script.aculo.us builder.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Builder = {
+ NODEMAP: {
+ AREA: 'map',
+ CAPTION: 'table',
+ COL: 'table',
+ COLGROUP: 'table',
+ LEGEND: 'fieldset',
+ OPTGROUP: 'select',
+ OPTION: 'select',
+ PARAM: 'object',
+ TBODY: 'table',
+ TD: 'table',
+ TFOOT: 'table',
+ TH: 'table',
+ THEAD: 'table',
+ TR: 'table'
+ },
+ // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+ // due to a Firefox bug
+ node: function(elementName) {
+ elementName = elementName.toUpperCase();
+
+ // try innerHTML approach
+ var parentTag = this.NODEMAP[elementName] || 'div';
+ var parentElement = document.createElement(parentTag);
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" + elementName + ">" + elementName + ">";
+ } catch(e) {}
+ var element = parentElement.firstChild || null;
+
+ // see if browser added wrapping tags
+ if(element && (element.tagName.toUpperCase() != elementName))
+ element = element.getElementsByTagName(elementName)[0];
+
+ // fallback to createElement approach
+ if(!element) element = document.createElement(elementName);
+
+ // abort if nothing could be created
+ if(!element) return;
+
+ // attributes (or text)
+ if(arguments[1])
+ if(this._isStringOrNumber(arguments[1]) ||
+ (arguments[1] instanceof Array) ||
+ arguments[1].tagName) {
+ this._children(element, arguments[1]);
+ } else {
+ var attrs = this._attributes(arguments[1]);
+ if(attrs.length) {
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" +elementName + " " +
+ attrs + ">" + elementName + ">";
+ } catch(e) {}
+ element = parentElement.firstChild || null;
+ // workaround firefox 1.0.X bug
+ if(!element) {
+ element = document.createElement(elementName);
+ for(attr in arguments[1])
+ element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
+ }
+ if(element.tagName.toUpperCase() != elementName)
+ element = parentElement.getElementsByTagName(elementName)[0];
+ }
+ }
+
+ // text, or array of children
+ if(arguments[2])
+ this._children(element, arguments[2]);
+
+ return element;
+ },
+ _text: function(text) {
+ return document.createTextNode(text);
+ },
+
+ ATTR_MAP: {
+ 'className': 'class',
+ 'htmlFor': 'for'
+ },
+
+ _attributes: function(attributes) {
+ var attrs = [];
+ for(attribute in attributes)
+ attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
+ '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'"') + '"');
+ return attrs.join(" ");
+ },
+ _children: function(element, children) {
+ if(children.tagName) {
+ element.appendChild(children);
+ return;
+ }
+ if(typeof children=='object') { // array can hold nodes and text
+ children.flatten().each( function(e) {
+ if(typeof e=='object')
+ element.appendChild(e)
+ else
+ if(Builder._isStringOrNumber(e))
+ element.appendChild(Builder._text(e));
+ });
+ } else
+ if(Builder._isStringOrNumber(children))
+ element.appendChild(Builder._text(children));
+ },
+ _isStringOrNumber: function(param) {
+ return(typeof param=='string' || typeof param=='number');
+ },
+ build: function(html) {
+ var element = this.node('div');
+ $(element).update(html.strip());
+ return element.down();
+ },
+ dump: function(scope) {
+ if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
+
+ var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
+ "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
+ "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
+ "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
+ "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
+ "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
+
+ tags.each( function(tag){
+ scope[tag] = function() {
+ return Builder.node.apply(Builder, [tag].concat($A(arguments)));
+ }
+ });
+ }
+}
diff --git a/js/effects.js b/js/effects.js
new file mode 100644
index 0000000..b7f3f0a
--- /dev/null
+++ b/js/effects.js
@@ -0,0 +1,1122 @@
+// script.aculo.us effects.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+// Justin Palmer (http://encytemedia.com/)
+// Mark Pilgrim (http://diveintomark.org/)
+// Martin Bialasinki
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
+ var color = '#';
+ if (this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if (this.slice(0,1) == '#') {
+ if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if (this.length==7) color = this.toLowerCase();
+ }
+ }
+ return (color.length==7 ? color : (arguments[0] || this));
+};
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+ }).flatten().join('');
+};
+
+Element.collectTextNodesIgnoreClass = function(element, className) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+ Element.collectTextNodesIgnoreClass(node, className) : ''));
+ }).flatten().join('');
+};
+
+Element.setContentZoom = function(element, percent) {
+ element = $(element);
+ element.setStyle({fontSize: (percent/100) + 'em'});
+ if (Prototype.Browser.WebKit) window.scrollBy(0,0);
+ return element;
+};
+
+Element.getInlineOpacity = function(element){
+ return $(element).style.opacity || '';
+};
+
+Element.forceRerendering = function(element) {
+ try {
+ element = $(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+ _elementDoesNotExistError: {
+ name: 'ElementDoesNotExistError',
+ message: 'The specified DOM element does not exist, but is required for this effect to operate'
+ },
+ Transitions: {
+ linear: Prototype.K,
+ sinoidal: function(pos) {
+ return (-Math.cos(pos*Math.PI)/2) + 0.5;
+ },
+ reverse: function(pos) {
+ return 1-pos;
+ },
+ flicker: function(pos) {
+ var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ return pos > 1 ? 1 : pos;
+ },
+ wobble: function(pos) {
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+ },
+ pulse: function(pos, pulses) {
+ pulses = pulses || 5;
+ return (
+ ((pos % (1/pulses)) * pulses).round() == 0 ?
+ ((pos * pulses * 2) - (pos * pulses * 2).floor()) :
+ 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
+ );
+ },
+ spring: function(pos) {
+ return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
+ },
+ none: function(pos) {
+ return 0;
+ },
+ full: function(pos) {
+ return 1;
+ }
+ },
+ DefaultOptions: {
+ duration: 1.0, // seconds
+ fps: 100, // 100= assume 66fps max.
+ sync: false, // true for combining
+ from: 0.0,
+ to: 1.0,
+ delay: 0.0,
+ queue: 'parallel'
+ },
+ tagifyText: function(element) {
+ var tagifyStyle = 'position:relative';
+ if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
+
+ element = $(element);
+ $A(element.childNodes).each( function(child) {
+ if (child.nodeType==3) {
+ child.nodeValue.toArray().each( function(character) {
+ element.insertBefore(
+ new Element('span', {style: tagifyStyle}).update(
+ character == ' ' ? String.fromCharCode(160) : character),
+ child);
+ });
+ Element.remove(child);
+ }
+ });
+ },
+ multiple: function(element, effect) {
+ var elements;
+ if (((typeof element == 'object') ||
+ Object.isFunction(element)) &&
+ (element.length))
+ elements = element;
+ else
+ elements = $(element).childNodes;
+
+ var options = Object.extend({
+ speed: 0.1,
+ delay: 0.0
+ }, arguments[2] || { });
+ var masterDelay = options.delay;
+
+ $A(elements).each( function(element, index) {
+ new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+ });
+ },
+ PAIRS: {
+ 'slide': ['SlideDown','SlideUp'],
+ 'blind': ['BlindDown','BlindUp'],
+ 'appear': ['Appear','Fade']
+ },
+ toggle: function(element, effect) {
+ element = $(element);
+ effect = (effect || 'appear').toLowerCase();
+ var options = Object.extend({
+ queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+ }, arguments[2] || { });
+ Effect[element.visible() ?
+ Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }
+};
+
+Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create(Enumerable, {
+ initialize: function() {
+ this.effects = [];
+ this.interval = null;
+ },
+ _each: function(iterator) {
+ this.effects._each(iterator);
+ },
+ add: function(effect) {
+ var timestamp = new Date().getTime();
+
+ var position = Object.isString(effect.options.queue) ?
+ effect.options.queue : effect.options.queue.position;
+
+ switch(position) {
+ case 'front':
+ // move unstarted effects after this effect
+ this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
+ e.startOn += effect.finishOn;
+ e.finishOn += effect.finishOn;
+ });
+ break;
+ case 'with-last':
+ timestamp = this.effects.pluck('startOn').max() || timestamp;
+ break;
+ case 'end':
+ // start effect after last queued effect has finished
+ timestamp = this.effects.pluck('finishOn').max() || timestamp;
+ break;
+ }
+
+ effect.startOn += timestamp;
+ effect.finishOn += timestamp;
+
+ if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+ this.effects.push(effect);
+
+ if (!this.interval)
+ this.interval = setInterval(this.loop.bind(this), 15);
+ },
+ remove: function(effect) {
+ this.effects = this.effects.reject(function(e) { return e==effect });
+ if (this.effects.length == 0) {
+ clearInterval(this.interval);
+ this.interval = null;
+ }
+ },
+ loop: function() {
+ var timePos = new Date().getTime();
+ for(var i=0, len=this.effects.length;i= this.startOn) {
+ if (timePos >= this.finishOn) {
+ this.render(1.0);
+ this.cancel();
+ this.event('beforeFinish');
+ if (this.finish) this.finish();
+ this.event('afterFinish');
+ return;
+ }
+ var pos = (timePos - this.startOn) / this.totalTime,
+ frame = (pos * this.totalFrames).round();
+ if (frame > this.currentFrame) {
+ this.render(pos);
+ this.currentFrame = frame;
+ }
+ }
+ },
+ cancel: function() {
+ if (!this.options.sync)
+ Effect.Queues.get(Object.isString(this.options.queue) ?
+ 'global' : this.options.queue.scope).remove(this);
+ this.state = 'finished';
+ },
+ event: function(eventName) {
+ if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+ if (this.options[eventName]) this.options[eventName](this);
+ },
+ inspect: function() {
+ var data = $H();
+ for(property in this)
+ if (!Object.isFunction(this[property])) data.set(property, this[property]);
+ return '#';
+ }
+});
+
+Effect.Parallel = Class.create(Effect.Base, {
+ initialize: function(effects) {
+ this.effects = effects || [];
+ this.start(arguments[1]);
+ },
+ update: function(position) {
+ this.effects.invoke('render', position);
+ },
+ finish: function(position) {
+ this.effects.each( function(effect) {
+ effect.render(1.0);
+ effect.cancel();
+ effect.event('beforeFinish');
+ if (effect.finish) effect.finish(position);
+ effect.event('afterFinish');
+ });
+ }
+});
+
+Effect.Tween = Class.create(Effect.Base, {
+ initialize: function(object, from, to) {
+ object = Object.isString(object) ? $(object) : object;
+ var args = $A(arguments), method = args.last(),
+ options = args.length == 5 ? args[3] : null;
+ this.method = Object.isFunction(method) ? method.bind(object) :
+ Object.isFunction(object[method]) ? object[method].bind(object) :
+ function(value) { object[method] = value };
+ this.start(Object.extend({ from: from, to: to }, options || { }));
+ },
+ update: function(position) {
+ this.method(position);
+ }
+});
+
+Effect.Event = Class.create(Effect.Base, {
+ initialize: function() {
+ this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
+ },
+ update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ // make this work on IE on elements without 'layout'
+ if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ var options = Object.extend({
+ from: this.element.getOpacity() || 0.0,
+ to: 1.0
+ }, arguments[1] || { });
+ this.start(options);
+ },
+ update: function(position) {
+ this.element.setOpacity(position);
+ }
+});
+
+Effect.Move = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ x: 0,
+ y: 0,
+ mode: 'relative'
+ }, arguments[1] || { });
+ this.start(options);
+ },
+ setup: function() {
+ this.element.makePositioned();
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+ this.originalTop = parseFloat(this.element.getStyle('top') || '0');
+ if (this.options.mode == 'absolute') {
+ this.options.x = this.options.x - this.originalLeft;
+ this.options.y = this.options.y - this.originalTop;
+ }
+ },
+ update: function(position) {
+ this.element.setStyle({
+ left: (this.options.x * position + this.originalLeft).round() + 'px',
+ top: (this.options.y * position + this.originalTop).round() + 'px'
+ });
+ }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+ return new Effect.Move(element,
+ Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
+};
+
+Effect.Scale = Class.create(Effect.Base, {
+ initialize: function(element, percent) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ scaleX: true,
+ scaleY: true,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleMode: 'box', // 'box' or 'contents' or { } with provided values
+ scaleFrom: 100.0,
+ scaleTo: percent
+ }, arguments[2] || { });
+ this.start(options);
+ },
+ setup: function() {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = this.element.getStyle('position');
+
+ this.originalStyle = { };
+ ['top','left','width','height','fontSize'].each( function(k) {
+ this.originalStyle[k] = this.element.style[k];
+ }.bind(this));
+
+ this.originalTop = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = this.element.getStyle('font-size') || '100%';
+ ['em','px','%','pt'].each( function(fontSizeType) {
+ if (fontSize.indexOf(fontSizeType)>0) {
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
+ }
+ }.bind(this));
+
+ this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+
+ this.dims = null;
+ if (this.options.scaleMode=='box')
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ if (/^content/.test(this.options.scaleMode))
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+ if (!this.dims)
+ this.dims = [this.options.scaleMode.originalHeight,
+ this.options.scaleMode.originalWidth];
+ },
+ update: function(position) {
+ var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+ if (this.options.scaleContent && this.fontSize)
+ this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+ this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+ },
+ finish: function(position) {
+ if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+ },
+ setDimensions: function(height, width) {
+ var d = { };
+ if (this.options.scaleX) d.width = width.round() + 'px';
+ if (this.options.scaleY) d.height = height.round() + 'px';
+ if (this.options.scaleFromCenter) {
+ var topd = (height - this.dims[0])/2;
+ var leftd = (width - this.dims[1])/2;
+ if (this.elementPositioning == 'absolute') {
+ if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
+ if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+ } else {
+ if (this.options.scaleY) d.top = -topd + 'px';
+ if (this.options.scaleX) d.left = -leftd + 'px';
+ }
+ }
+ this.element.setStyle(d);
+ }
+});
+
+Effect.Highlight = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
+ this.start(options);
+ },
+ setup: function() {
+ // Prevent executing on elements not in the layout flow
+ if (this.element.getStyle('display')=='none') { this.cancel(); return; }
+ // Disable background image during the effect
+ this.oldStyle = { };
+ if (!this.options.keepBackgroundImage) {
+ this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+ this.element.setStyle({backgroundImage: 'none'});
+ }
+ if (!this.options.endcolor)
+ this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+ if (!this.options.restorecolor)
+ this.options.restorecolor = this.element.getStyle('background-color');
+ // init color calculations
+ this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+ this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+ },
+ update: function(position) {
+ this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+ return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
+ },
+ finish: function() {
+ this.element.setStyle(Object.extend(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
+ }
+});
+
+Effect.ScrollTo = function(element) {
+ var options = arguments[1] || { },
+ scrollOffsets = document.viewport.getScrollOffsets(),
+ elementOffsets = $(element).cumulativeOffset(),
+ max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();
+
+ if (options.offset) elementOffsets[1] += options.offset;
+
+ return new Effect.Tween(null,
+ scrollOffsets.top,
+ elementOffsets[1] > max ? max : elementOffsets[1],
+ options,
+ function(p){ scrollTo(scrollOffsets.left, p.round()) }
+ );
+};
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ var options = Object.extend({
+ from: element.getOpacity() || 1.0,
+ to: 0.0,
+ afterFinishInternal: function(effect) {
+ if (effect.options.to!=0) return;
+ effect.element.hide().setStyle({opacity: oldOpacity});
+ }
+ }, arguments[1] || { });
+ return new Effect.Opacity(element,options);
+};
+
+Effect.Appear = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+ to: 1.0,
+ // force Safari to render floated elements properly
+ afterFinishInternal: function(effect) {
+ effect.element.forceRerendering();
+ },
+ beforeSetup: function(effect) {
+ effect.element.setOpacity(effect.options.from).show();
+ }}, arguments[1] || { });
+ return new Effect.Opacity(element,options);
+};
+
+Effect.Puff = function(element) {
+ element = $(element);
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
+ position: element.getStyle('position'),
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+ };
+ return new Effect.Parallel(
+ [ new Effect.Scale(element, 200,
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+ Object.extend({ duration: 1.0,
+ beforeSetupInternal: function(effect) {
+ Position.absolutize(effect.effects[0].element)
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().setStyle(oldStyle); }
+ }, arguments[1] || { })
+ );
+};
+
+Effect.BlindUp = function(element) {
+ element = $(element);
+ element.makeClipping();
+ return new Effect.Scale(element, 0,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ restoreAfterFinish: true,
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
+ }, arguments[1] || { })
+ );
+};
+
+Effect.BlindDown = function(element) {
+ element = $(element);
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || { }));
+};
+
+Effect.SwitchOff = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ return new Effect.Appear(element, Object.extend({
+ duration: 0.4,
+ from: 0,
+ transition: Effect.Transitions.flicker,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(effect.element, 1, {
+ duration: 0.3, scaleFromCenter: true,
+ scaleX: false, scaleContent: false, restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makePositioned().makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+ }
+ })
+ }
+ }, arguments[1] || { }));
+};
+
+Effect.DropOut = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left'),
+ opacity: element.getInlineOpacity() };
+ return new Effect.Parallel(
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+ Object.extend(
+ { duration: 0.5,
+ beforeSetup: function(effect) {
+ effect.effects[0].element.makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+ }
+ }, arguments[1] || { }));
+};
+
+Effect.Shake = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ distance: 20,
+ duration: 0.5
+ }, arguments[1] || {});
+ var distance = parseFloat(options.distance);
+ var split = parseFloat(options.duration) / 10.0;
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left') };
+ return new Effect.Move(element,
+ { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+ effect.element.undoPositioned().setStyle(oldStyle);
+ }}) }}) }}) }}) }}) }});
+};
+
+Effect.SlideDown = function(element) {
+ element = $(element).cleanWhitespace();
+ // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+ var oldInnerBottom = element.down().getStyle('bottom');
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: window.opera ? 0 : 1,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.down().makePositioned();
+ if (window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterUpdateInternal: function(effect) {
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
+ }, arguments[1] || { })
+ );
+};
+
+Effect.SlideUp = function(element) {
+ element = $(element).cleanWhitespace();
+ var oldInnerBottom = element.down().getStyle('bottom');
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, window.opera ? 0 : 1,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ scaleMode: 'box',
+ scaleFrom: 100,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.down().makePositioned();
+ if (window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping().show();
+ },
+ afterUpdateInternal: function(effect) {
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
+ }
+ }, arguments[1] || { })
+ );
+};
+
+// Bug in opera makes the TD containing this element expand for a instance after finish
+Effect.Squish = function(element) {
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
+ restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
+ });
+};
+
+Effect.Grow = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.full
+ }, arguments[1] || { });
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var initialMoveX, initialMoveY;
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ initialMoveX = initialMoveY = moveX = moveY = 0;
+ break;
+ case 'top-right':
+ initialMoveX = dims.width;
+ initialMoveY = moveY = 0;
+ moveX = -dims.width;
+ break;
+ case 'bottom-left':
+ initialMoveX = moveX = 0;
+ initialMoveY = dims.height;
+ moveY = -dims.height;
+ break;
+ case 'bottom-right':
+ initialMoveX = dims.width;
+ initialMoveY = dims.height;
+ moveX = -dims.width;
+ moveY = -dims.height;
+ break;
+ case 'center':
+ initialMoveX = dims.width / 2;
+ initialMoveY = dims.height / 2;
+ moveX = -dims.width / 2;
+ moveY = -dims.height / 2;
+ break;
+ }
+
+ return new Effect.Move(element, {
+ x: initialMoveX,
+ y: initialMoveY,
+ duration: 0.01,
+ beforeSetup: function(effect) {
+ effect.element.hide().makeClipping().makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ new Effect.Parallel(
+ [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+ new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+ new Effect.Scale(effect.element, 100, {
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+ ], Object.extend({
+ beforeSetup: function(effect) {
+ effect.effects[0].element.setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+ }
+ }, options)
+ )
+ }
+ });
+};
+
+Effect.Shrink = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.none
+ }, arguments[1] || { });
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ moveX = moveY = 0;
+ break;
+ case 'top-right':
+ moveX = dims.width;
+ moveY = 0;
+ break;
+ case 'bottom-left':
+ moveX = 0;
+ moveY = dims.height;
+ break;
+ case 'bottom-right':
+ moveX = dims.width;
+ moveY = dims.height;
+ break;
+ case 'center':
+ moveX = dims.width / 2;
+ moveY = dims.height / 2;
+ break;
+ }
+
+ return new Effect.Parallel(
+ [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+ new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+ new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+ ], Object.extend({
+ beforeStartInternal: function(effect) {
+ effect.effects[0].element.makePositioned().makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
+ }, options)
+ );
+};
+
+Effect.Pulsate = function(element) {
+ element = $(element);
+ var options = arguments[1] || { };
+ var oldOpacity = element.getInlineOpacity();
+ var transition = options.transition || Effect.Transitions.sinoidal;
+ var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
+ reverser.bind(transition);
+ return new Effect.Opacity(element,
+ Object.extend(Object.extend({ duration: 2.0, from: 0,
+ afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+ }, options), {transition: reverser}));
+};
+
+Effect.Fold = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height };
+ element.makeClipping();
+ return new Effect.Scale(element, 5, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
+ scaleY: false,
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().setStyle(oldStyle);
+ } });
+ }}, arguments[1] || { }));
+};
+
+Effect.Morph = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ style: { }
+ }, arguments[1] || { });
+
+ if (!Object.isString(options.style)) this.style = $H(options.style);
+ else {
+ if (options.style.include(':'))
+ this.style = options.style.parseStyle();
+ else {
+ this.element.addClassName(options.style);
+ this.style = $H(this.element.getStyles());
+ this.element.removeClassName(options.style);
+ var css = this.element.getStyles();
+ this.style = this.style.reject(function(style) {
+ return style.value == css[style.key];
+ });
+ options.afterFinishInternal = function(effect) {
+ effect.element.addClassName(effect.options.style);
+ effect.transforms.each(function(transform) {
+ effect.element.style[transform.style] = '';
+ });
+ }
+ }
+ }
+ this.start(options);
+ },
+
+ setup: function(){
+ function parseColor(color){
+ if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+ color = color.parseColor();
+ return $R(0,2).map(function(i){
+ return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ });
+ }
+ this.transforms = this.style.map(function(pair){
+ var property = pair[0], value = pair[1], unit = null;
+
+ if (value.parseColor('#zzzzzz') != '#zzzzzz') {
+ value = value.parseColor();
+ unit = 'color';
+ } else if (property == 'opacity') {
+ value = parseFloat(value);
+ if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ } else if (Element.CSS_LENGTH.test(value)) {
+ var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+ value = parseFloat(components[1]);
+ unit = (components.length == 3) ? components[2] : null;
+ }
+
+ var originalValue = this.element.getStyle(property);
+ return {
+ style: property.camelize(),
+ originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+ targetValue: unit=='color' ? parseColor(value) : value,
+ unit: unit
+ };
+ }.bind(this)).reject(function(transform){
+ return (
+ (transform.originalValue == transform.targetValue) ||
+ (
+ transform.unit != 'color' &&
+ (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+ )
+ )
+ });
+ },
+ update: function(position) {
+ var style = { }, transform, i = this.transforms.length;
+ while(i--)
+ style[(transform = this.transforms[i]).style] =
+ transform.unit=='color' ? '#'+
+ (Math.round(transform.originalValue[0]+
+ (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
+ (Math.round(transform.originalValue[1]+
+ (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
+ (Math.round(transform.originalValue[2]+
+ (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
+ (transform.originalValue +
+ (transform.targetValue - transform.originalValue) * position).toFixed(3) +
+ (transform.unit === null ? '' : transform.unit);
+ this.element.setStyle(style, true);
+ }
+});
+
+Effect.Transform = Class.create({
+ initialize: function(tracks){
+ this.tracks = [];
+ this.options = arguments[1] || { };
+ this.addTracks(tracks);
+ },
+ addTracks: function(tracks){
+ tracks.each(function(track){
+ track = $H(track);
+ var data = track.values().first();
+ this.tracks.push($H({
+ ids: track.keys().first(),
+ effect: Effect.Morph,
+ options: { style: data }
+ }));
+ }.bind(this));
+ return this;
+ },
+ play: function(){
+ return new Effect.Parallel(
+ this.tracks.map(function(track){
+ var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
+ var elements = [$(ids) || $$(ids)].flatten();
+ return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
+ }).flatten(),
+ this.options
+ );
+ }
+});
+
+Element.CSS_PROPERTIES = $w(
+ 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+ 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+ 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+ 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+ 'fontSize fontWeight height left letterSpacing lineHeight ' +
+ 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+ 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+ 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+ 'right textIndent top width wordSpacing zIndex');
+
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.__parseStyleElement = document.createElement('div');
+String.prototype.parseStyle = function(){
+ var style, styleRules = $H();
+ if (Prototype.Browser.WebKit)
+ style = new Element('div',{style:this}).style;
+ else {
+ String.__parseStyleElement.innerHTML = '
';
+ style = String.__parseStyleElement.childNodes[0].style;
+ }
+
+ Element.CSS_PROPERTIES.each(function(property){
+ if (style[property]) styleRules.set(property, style[property]);
+ });
+
+ if (Prototype.Browser.IE && this.include('opacity'))
+ styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
+
+ return styleRules;
+};
+
+if (document.defaultView && document.defaultView.getComputedStyle) {
+ Element.getStyles = function(element) {
+ var css = document.defaultView.getComputedStyle($(element), null);
+ return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
+ styles[property] = css[property];
+ return styles;
+ });
+ };
+} else {
+ Element.getStyles = function(element) {
+ element = $(element);
+ var css = element.currentStyle, styles;
+ styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
+ results[property] = css[property];
+ return results;
+ });
+ if (!styles.opacity) styles.opacity = element.getOpacity();
+ return styles;
+ };
+};
+
+Effect.Methods = {
+ morph: function(element, style) {
+ element = $(element);
+ new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
+ return element;
+ },
+ visualEffect: function(element, effect, options) {
+ element = $(element)
+ var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[klass](element, options);
+ return element;
+ },
+ highlight: function(element, options) {
+ element = $(element);
+ new Effect.Highlight(element, options);
+ return element;
+ }
+};
+
+$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
+ 'pulsate shake puff squish switchOff dropOut').each(
+ function(effect) {
+ Effect.Methods[effect] = function(element, options){
+ element = $(element);
+ Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
+ return element;
+ }
+ }
+);
+
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
+ function(f) { Effect.Methods[f] = Element[f]; }
+);
+
+Element.addMethods(Effect.Methods);
diff --git a/js/lightbox.js b/js/lightbox.js
new file mode 100644
index 0000000..907e20c
--- /dev/null
+++ b/js/lightbox.js
@@ -0,0 +1,497 @@
+// -----------------------------------------------------------------------------------
+//
+// Lightbox v2.04
+// by Lokesh Dhakar - http://www.lokeshdhakar.com
+// Last Modification: 2/9/08
+//
+// For more information, visit:
+// http://lokeshdhakar.com/projects/lightbox2/
+//
+// Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
+// - Free for use in both personal and commercial projects
+// - Attribution requires leaving author name, author link, and the license info intact.
+//
+// Thanks: Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), and Thomas Fuchs(mir.aculo.us) for ideas, libs, and snippets.
+// Artemy Tregubenko (arty.name) for cleanup and help in updating to latest ver of proto-aculous.
+//
+// -----------------------------------------------------------------------------------
+/*
+
+ Table of Contents
+ -----------------
+ Configuration
+
+ Lightbox Class Declaration
+ - initialize()
+ - updateImageList()
+ - start()
+ - changeImage()
+ - resizeImageContainer()
+ - showImage()
+ - updateDetails()
+ - updateNav()
+ - enableKeyboardNav()
+ - disableKeyboardNav()
+ - keyboardAction()
+ - preloadNeighborImages()
+ - end()
+
+ Function Calls
+ - document.observe()
+
+*/
+// -----------------------------------------------------------------------------------
+
+//
+// Configurationl
+//
+LightboxOptions = Object.extend({
+ fileLoadingImage: 'images/loading.gif',
+ fileBottomNavCloseImage: 'images/closelabel.gif',
+
+ overlayOpacity: 0.8, // controls transparency of shadow overlay
+
+ animate: true, // toggles resizing animations
+ resizeSpeed: 7, // controls the speed of the image resizing animations (1=slowest and 10=fastest)
+
+ borderSize: 10, //if you adjust the padding in the CSS, you will need to update this variable
+
+ // When grouping images this is used to write: Image # of #.
+ // Change it for non-english localization
+ labelImage: "Image",
+ labelOf: "of"
+}, window.LightboxOptions || {});
+
+// -----------------------------------------------------------------------------------
+
+var Lightbox = Class.create();
+
+Lightbox.prototype = {
+ imageArray: [],
+ activeImage: undefined,
+
+ // initialize()
+ // Constructor runs on completion of the DOM loading. Calls updateImageList and then
+ // the function inserts html at the bottom of the page which is used to display the shadow
+ // overlay and the image container.
+ //
+ initialize: function() {
+
+ this.updateImageList();
+
+ this.keyboardAction = this.keyboardAction.bindAsEventListener(this);
+
+ if (LightboxOptions.resizeSpeed > 10) LightboxOptions.resizeSpeed = 10;
+ if (LightboxOptions.resizeSpeed < 1) LightboxOptions.resizeSpeed = 1;
+
+ this.resizeDuration = LightboxOptions.animate ? ((11 - LightboxOptions.resizeSpeed) * 0.15) : 0;
+ this.overlayDuration = LightboxOptions.animate ? 0.2 : 0; // shadow fade in/out duration
+
+ // When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
+ // If animations are turned off, it will be hidden as to prevent a flicker of a
+ // white 250 by 250 box.
+ var size = (LightboxOptions.animate ? 250 : 1) + 'px';
+
+
+ // Code inserts html at the bottom of the page that looks similar to this:
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+
+
+ var objBody = $$('body')[0];
+
+ objBody.appendChild(Builder.node('div',{id:'overlay'}));
+
+ objBody.appendChild(Builder.node('div',{id:'lightbox'}, [
+ Builder.node('div',{id:'outerImageContainer'},
+ Builder.node('div',{id:'imageContainer'}, [
+ Builder.node('img',{id:'lightboxImage'}),
+ Builder.node('div',{id:'hoverNav'}, [
+ Builder.node('a',{id:'prevLink', href: '#' }),
+ Builder.node('a',{id:'nextLink', href: '#' })
+ ]),
+ Builder.node('div',{id:'loading'},
+ Builder.node('a',{id:'loadingLink', href: '#' },
+ Builder.node('img', {src: LightboxOptions.fileLoadingImage})
+ )
+ )
+ ])
+ ),
+ Builder.node('div', {id:'imageDataContainer'},
+ Builder.node('div',{id:'imageData'}, [
+ Builder.node('div',{id:'imageDetails'}, [
+ Builder.node('span',{id:'caption'}),
+ Builder.node('span',{id:'numberDisplay'})
+ ]),
+ Builder.node('div',{id:'bottomNav'},
+ Builder.node('a',{id:'bottomNavClose', href: '#' },
+ Builder.node('img', { src: LightboxOptions.fileBottomNavCloseImage })
+ )
+ )
+ ])
+ )
+ ]));
+
+
+ $('overlay').hide().observe('click', (function() { this.end(); }).bind(this));
+ $('lightbox').hide().observe('click', (function(event) { if (event.element().id == 'lightbox') this.end(); }).bind(this));
+ $('outerImageContainer').setStyle({ width: size, height: size });
+ $('prevLink').observe('click', (function(event) { event.stop(); this.changeImage(this.activeImage - 1); }).bindAsEventListener(this));
+ $('nextLink').observe('click', (function(event) { event.stop(); this.changeImage(this.activeImage + 1); }).bindAsEventListener(this));
+ $('loadingLink').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));
+ $('bottomNavClose').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));
+
+ var th = this;
+ (function(){
+ var ids =
+ 'overlay lightbox outerImageContainer imageContainer lightboxImage hoverNav prevLink nextLink loading loadingLink ' +
+ 'imageDataContainer imageData imageDetails caption numberDisplay bottomNav bottomNavClose';
+ $w(ids).each(function(id){ th[id] = $(id); });
+ }).defer();
+ },
+
+ //
+ // updateImageList()
+ // Loops through anchor tags looking for 'lightbox' references and applies onclick
+ // events to appropriate links. You can rerun after dynamically adding images w/ajax.
+ //
+ updateImageList: function() {
+ this.updateImageList = Prototype.emptyFunction;
+
+ document.observe('click', (function(event){
+ var target = event.findElement('a[rel^=lightbox]') || event.findElement('area[rel^=lightbox]');
+ if (target) {
+ event.stop();
+ this.start(target);
+ }
+ }).bind(this));
+ },
+
+ //
+ // start()
+ // Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
+ //
+ start: function(imageLink) {
+
+ $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });
+
+ // stretch overlay to fill page and fade in
+ var arrayPageSize = this.getPageSize();
+ $('overlay').setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });
+
+ new Effect.Appear(this.overlay, { duration: this.overlayDuration, from: 0.0, to: LightboxOptions.overlayOpacity });
+
+ this.imageArray = [];
+ var imageNum = 0;
+
+ if ((imageLink.rel == 'lightbox')){
+ // if image is NOT part of a set, add single image to imageArray
+ this.imageArray.push([imageLink.href, imageLink.title]);
+ } else {
+ // if image is part of a set..
+ this.imageArray =
+ $$(imageLink.tagName + '[href][rel="' + imageLink.rel + '"]').
+ collect(function(anchor){ return [anchor.href, anchor.title]; }).
+ uniq();
+
+ while (this.imageArray[imageNum][0] != imageLink.href) { imageNum++; }
+ }
+
+ // calculate top and left offset for the lightbox
+ var arrayPageScroll = document.viewport.getScrollOffsets();
+ var lightboxTop = arrayPageScroll[1] + (document.viewport.getHeight() / 10);
+ var lightboxLeft = arrayPageScroll[0];
+ this.lightbox.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();
+
+ this.changeImage(imageNum);
+ },
+
+ //
+ // changeImage()
+ // Hide most elements and preload image in preparation for resizing image container.
+ //
+ changeImage: function(imageNum) {
+
+ this.activeImage = imageNum; // update global var
+
+ // hide elements during transition
+ if (LightboxOptions.animate) this.loading.show();
+ this.lightboxImage.hide();
+ this.hoverNav.hide();
+ this.prevLink.hide();
+ this.nextLink.hide();
+ // HACK: Opera9 does not currently support scriptaculous opacity and appear fx
+ this.imageDataContainer.setStyle({opacity: .0001});
+ this.numberDisplay.hide();
+
+ var imgPreloader = new Image();
+
+ // once image is preloaded, resize image container
+
+
+ imgPreloader.onload = (function(){
+ this.lightboxImage.src = this.imageArray[this.activeImage][0];
+ this.resizeImageContainer(imgPreloader.width, imgPreloader.height);
+ }).bind(this);
+ imgPreloader.src = this.imageArray[this.activeImage][0];
+ },
+
+ //
+ // resizeImageContainer()
+ //
+ resizeImageContainer: function(imgWidth, imgHeight) {
+
+ // get current width and height
+ var widthCurrent = this.outerImageContainer.getWidth();
+ var heightCurrent = this.outerImageContainer.getHeight();
+
+ // get new width and height
+ var widthNew = (imgWidth + LightboxOptions.borderSize * 2);
+ var heightNew = (imgHeight + LightboxOptions.borderSize * 2);
+
+ // scalars based on change from old to new
+ var xScale = (widthNew / widthCurrent) * 100;
+ var yScale = (heightNew / heightCurrent) * 100;
+
+ // calculate size difference between new and old image, and resize if necessary
+ var wDiff = widthCurrent - widthNew;
+ var hDiff = heightCurrent - heightNew;
+
+ if (hDiff != 0) new Effect.Scale(this.outerImageContainer, yScale, {scaleX: false, duration: this.resizeDuration, queue: 'front'});
+ if (wDiff != 0) new Effect.Scale(this.outerImageContainer, xScale, {scaleY: false, duration: this.resizeDuration, delay: this.resizeDuration});
+
+ // if new and old image are same size and no scaling transition is necessary,
+ // do a quick pause to prevent image flicker.
+ var timeout = 0;
+ if ((hDiff == 0) && (wDiff == 0)){
+ timeout = 100;
+ if (Prototype.Browser.IE) timeout = 250;
+ }
+
+ (function(){
+ this.prevLink.setStyle({ height: imgHeight + 'px' });
+ this.nextLink.setStyle({ height: imgHeight + 'px' });
+ this.imageDataContainer.setStyle({ width: widthNew + 'px' });
+
+ this.showImage();
+ }).bind(this).delay(timeout / 1000);
+ },
+
+ //
+ // showImage()
+ // Display image and begin preloading neighbors.
+ //
+ showImage: function(){
+ this.loading.hide();
+ new Effect.Appear(this.lightboxImage, {
+ duration: this.resizeDuration,
+ queue: 'end',
+ afterFinish: (function(){ this.updateDetails(); }).bind(this)
+ });
+ this.preloadNeighborImages();
+ },
+
+ //
+ // updateDetails()
+ // Display caption, image number, and bottom nav.
+ //
+ updateDetails: function() {
+
+ // if caption is not null
+ if (this.imageArray[this.activeImage][1] != ""){
+ this.caption.update(this.imageArray[this.activeImage][1]).show();
+ }
+
+ // if image is part of set display 'Image x of x'
+ if (this.imageArray.length > 1){
+ this.numberDisplay.update( LightboxOptions.labelImage + ' ' + (this.activeImage + 1) + ' ' + LightboxOptions.labelOf + ' ' + this.imageArray.length).show();
+ }
+
+ new Effect.Parallel(
+ [
+ new Effect.SlideDown(this.imageDataContainer, { sync: true, duration: this.resizeDuration, from: 0.0, to: 1.0 }),
+ new Effect.Appear(this.imageDataContainer, { sync: true, duration: this.resizeDuration })
+ ],
+ {
+ duration: this.resizeDuration,
+ afterFinish: (function() {
+ // update overlay size and update nav
+ var arrayPageSize = this.getPageSize();
+ this.overlay.setStyle({ height: arrayPageSize[1] + 'px' });
+ this.updateNav();
+ }).bind(this)
+ }
+ );
+ },
+
+ //
+ // updateNav()
+ // Display appropriate previous and next hover navigation.
+ //
+ updateNav: function() {
+
+ this.hoverNav.show();
+
+ // if not first image in set, display prev image button
+ if (this.activeImage > 0) this.prevLink.show();
+
+ // if not last image in set, display next image button
+ if (this.activeImage < (this.imageArray.length - 1)) this.nextLink.show();
+
+ this.enableKeyboardNav();
+ },
+
+ //
+ // enableKeyboardNav()
+ //
+ enableKeyboardNav: function() {
+ document.observe('keydown', this.keyboardAction);
+ },
+
+ //
+ // disableKeyboardNav()
+ //
+ disableKeyboardNav: function() {
+ document.stopObserving('keydown', this.keyboardAction);
+ },
+
+ //
+ // keyboardAction()
+ //
+ keyboardAction: function(event) {
+ var keycode = event.keyCode;
+
+ var escapeKey;
+ if (event.DOM_VK_ESCAPE) { // mozilla
+ escapeKey = event.DOM_VK_ESCAPE;
+ } else { // ie
+ escapeKey = 27;
+ }
+
+ var key = String.fromCharCode(keycode).toLowerCase();
+
+ if (key.match(/x|o|c/) || (keycode == escapeKey)){ // close lightbox
+ this.end();
+ } else if ((key == 'p') || (keycode == 37)){ // display previous image
+ if (this.activeImage != 0){
+ this.disableKeyboardNav();
+ this.changeImage(this.activeImage - 1);
+ }
+ } else if ((key == 'n') || (keycode == 39)){ // display next image
+ if (this.activeImage != (this.imageArray.length - 1)){
+ this.disableKeyboardNav();
+ this.changeImage(this.activeImage + 1);
+ }
+ }
+ },
+
+ //
+ // preloadNeighborImages()
+ // Preload previous and next images.
+ //
+ preloadNeighborImages: function(){
+ var preloadNextImage, preloadPrevImage;
+ if (this.imageArray.length > this.activeImage + 1){
+ preloadNextImage = new Image();
+ preloadNextImage.src = this.imageArray[this.activeImage + 1][0];
+ }
+ if (this.activeImage > 0){
+ preloadPrevImage = new Image();
+ preloadPrevImage.src = this.imageArray[this.activeImage - 1][0];
+ }
+
+ },
+
+ //
+ // end()
+ //
+ end: function() {
+ this.disableKeyboardNav();
+ this.lightbox.hide();
+ new Effect.Fade(this.overlay, { duration: this.overlayDuration });
+ $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
+ },
+
+ //
+ // getPageSize()
+ //
+ getPageSize: function() {
+
+ var xScroll, yScroll;
+
+ if (window.innerHeight && window.scrollMaxY) {
+ xScroll = window.innerWidth + window.scrollMaxX;
+ yScroll = window.innerHeight + window.scrollMaxY;
+ } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
+ xScroll = document.body.scrollWidth;
+ yScroll = document.body.scrollHeight;
+ } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
+ xScroll = document.body.offsetWidth;
+ yScroll = document.body.offsetHeight;
+ }
+
+ var windowWidth, windowHeight;
+
+ if (self.innerHeight) { // all except Explorer
+ if(document.documentElement.clientWidth){
+ windowWidth = document.documentElement.clientWidth;
+ } else {
+ windowWidth = self.innerWidth;
+ }
+ windowHeight = self.innerHeight;
+ } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+ windowWidth = document.documentElement.clientWidth;
+ windowHeight = document.documentElement.clientHeight;
+ } else if (document.body) { // other Explorers
+ windowWidth = document.body.clientWidth;
+ windowHeight = document.body.clientHeight;
+ }
+
+ // for small pages with total height less then height of the viewport
+ if(yScroll < windowHeight){
+ pageHeight = windowHeight;
+ } else {
+ pageHeight = yScroll;
+ }
+
+ // for small pages with total width less then width of the viewport
+ if(xScroll < windowWidth){
+ pageWidth = xScroll;
+ } else {
+ pageWidth = windowWidth;
+ }
+
+ return [pageWidth,pageHeight];
+ }
+}
+
+document.observe('dom:loaded', function () { new Lightbox(); });
\ No newline at end of file
diff --git a/js/prototype.js b/js/prototype.js
new file mode 100644
index 0000000..16a3cd9
--- /dev/null
+++ b/js/prototype.js
@@ -0,0 +1,4221 @@
+/* Prototype JavaScript framework, version 1.6.0.2
+ * (c) 2005-2008 Sam Stephenson
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.6.0.2',
+
+ Browser: {
+ IE: !!(window.attachEvent && !window.opera),
+ Opera: !!window.opera,
+ WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
+ MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+ },
+
+ BrowserFeatures: {
+ XPath: !!document.evaluate,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ document.createElement('div').__proto__ &&
+ document.createElement('div').__proto__ !==
+ document.createElement('form').__proto__
+ },
+
+ ScriptFragment: '