/*
 * @include "/zooma/resources/jquery-1.4.2.min.js"
 */
document.documentElement.id = "js";

function fix_png ( t ) {
/*	filter: expression(fix_png(this))	*/
	if (/MSIE (5\.5|6).+Win/.test(navigator.userAgent)) {
		var src;
		if (t.tagName == 'IMG') {
			if (/\.png$/.test(t.src)) {
				src = t.src;
				t.src = "./i/e.gif";
			}
		} else {
			src = t.currentStyle.backgroundImage.match(/url\("(.+\.png)"\)/i);
			if (src) {
				src = src[1];
				t.runtimeStyle.backgroundImage = "none";
			}
		}
		var re_scale_mode = /iesizing\-(\w+)/;
		var m = re_scale_mode.exec(t.className);
		var scale_mode = (m) ? m[1] : 'crop';
		if (src) t.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "',sizingMethod='" + scale_mode + "')";
	}
}

jQuery(function($){
	var options = {
			literals: {
				catalog_item:		".b-cat_item",
				big_photo:			".b-big_photo_pic",
				thumb_wrap:			".b-thumb-wrap",
				thumb_pic:			".b-thumb_pic",
				selected_class:		"b-thumb_current",
				hover_class:		"b-thumb_hover",
				more_photos_class:	"b-big_photo_more"
			}
		},
		thumb_panels = [];
	fixIE6layout();
	preloadBigPhotos();
	slideShow( $( '.b-cat ' + options.literals.catalog_item ) );
	complect_enable(
		{
			thumb_panel:			'b-thumbs_panel',
			features:				'b-features',
			features_item:			'b-component-icon',
			features_item_selected:	'b-component-icon_current',
			details:				'b-details',
			details_item:			'b-details-item',
			details_item_selected:	'b-details-item_current',
			main_frame:				'b-details__main-frame',
			menu:					'b-details__menu',
			menu_item:				'item',
			menu_item_selected:		'item_current',
			menu_item_parent:		'item_parent',
			submenu:				'submenu',
			menu_link:				'link'
		}
	);
	enable_topmenu(
		{
			topmenu:				'b-topmenu',
			topmenu_item:			'b-topmenu__item',
			item_selected_postfix:	'_selected'
		}
	);
	enable_tabs(
		{
			tabs:				'midd',
			local_tabs:			'midd_local-tabs',
			tabs_panel:			'b-midmenu',
			tab_item:			'b-midmenu__item',
			tab_selected:		'b-midmenu__item_selected',
			tab_id_prefix:		'tab_',
			content:			'cont',
			content_item:		'b-content__item',
			content_selected:	'b-content__item_selected',
			content_id_prefix:	'cont_',
			tab_decor_l:		'b-tab__decor_tl',
			edge_mode:          'midd_edge-tabs',
			first_selected:     'b-midmenu__item_first_selected',
			last_selected:      'b-midmenu__item_last_selected'
		}
	);
	
	enable_cross_link_in_catalog_index (
		{
			item: 					'b-item_small',
			img: 					'b-item_small__img',
			header:					'b-item_small__text__header',
			img_highlight_class:	'b-item_small__img_select',
			header_highlight_class:	'b-item_small__text__header_select'
		}
	);

	function preloadBigPhotos() {
		$.preload( options.literals.thumb_pic, {
			find:/_thumb_?s?/,
			replace:''
		});
		$.preload( [ 'frame_bg_grey', 'frame_bg_blue'], {
	 		base:'/resources/img/',
	 		ext:'.gif'
	 	});
	}
	
	function slideShow(/*jQuery*/ elements) {
		if (!elements.size()) return;
		activateThumbs(elements);
	}
	
	function activateThumbs(/*jQuery*/ elements) {
		for (var i = 0; i < elements.length; i++) {
			if ( !$(options.literals.thumb_wrap, elements[i]).size() ) continue;
			var oThumbPanel = new ThumbPanel ($(elements[i]), i);
			oThumbPanel.init();
			thumb_panels.push( oThumbPanel );
		}
	}
	
	function ThumbPanel (/*jQuery*/ catalog_item, /*Number*/ id) {
		return {
			id: 					id,
			elt: 					catalog_item,
			$thumbs:				$( options.literals.thumb_wrap, catalog_item ),
			literals: 				options.literals,
			thumbs:					[],
			thumb_links:			[],
			details_menu:			undefined,
			features:				undefined,
			big_photo_elt: 			undefined,
			current_thumb: 			undefined,
			_master_mode:			new ModeController(),
			duration_change_photo: 	200,
			init: function(){
				this.set_big_photo_elt();
				for (var i = 0, l = this.$thumbs.length; i < l; i++) {
					var oThumb = new Thumb( $( this.$thumbs[i] ), this, i );
					oThumb.init();
					this.thumbs.push( oThumb );
					this.thumb_links.push( oThumb.link );
				}
				this.set_current_thumb();
				this.activate_big_photo();
				this.is_slave( true );
			},
			activate_big_photo: function() {
				if(this.thumbs.length <= 1) return;
				var $big_photo = this.big_photo_elt;
				$big_photo.addClass(this.literals.more_photos_class);
				$big_photo.bind("click", {thumbPanel: this}, this.big_photo_click);
			},
			big_photo_click: function( /*Event*/ evt ) {
				evt.preventDefault();
				var tp = evt.data.thumbPanel, 
					total_photos = tp.thumbs.length,
					current_photo = tp.get_current_thumb(),
					next_photo = current_photo + 1;
				next_photo = next_photo < total_photos ? next_photo : 0;
				tp.is_master( true );
				tp.update_big_photo(next_photo);
			},
			get_big_photo_elt: function() {
				return this.big_photo_elt;
			},
			set_big_photo_elt: function() {
				this.big_photo_elt = $(this.literals.big_photo, this.elt);
			},
			get_id: function() {
				return this.id;
			},
			activate_details_connection: function ( /*DetailsMenu*/ details_menu ) {
				this.details_menu = details_menu;
				this.show_details = this.show_details_work;
			},
			activate_features_connection: function ( /*Features*/ features ) {
				this.features = features;
				this.update_features = this.update_features_work;
			},
			get_thumb_by_link: function ( /*String*/ link ) {
				var thumb_links = this.thumb_links;
				for (var i = 0, l = thumb_links.length; i < l; i++) {
					if ( thumb_links[i] == link ) return this.thumbs[i];
				}
//				console.log( 'thumb with link "' + link + '" was not found.'  );
				return false;
			},
			trigger: function ( /*String*/ link ) {
				var thumb = this.get_thumb_by_link( link );
				if ( thumb ) {
//					console.log( 'trigger : ' + thumb );
					thumb.trigger();
				}
			},
			big_pic_exists_by_link: function ( /*String*/ link ) {
				return this.get_thumb_by_link( link );
			},
			get_current_thumb: function() {
				return this.current_thumb;
			},
			set_current_thumb: function(/*Number*/ /*id*/) {
				if(arguments.length) {
					this.current_thumb = arguments[0];
				} else {
					var $current_thumb = $( '.' + this.literals.selected_class, this.elt );
					if ( $current_thumb.size() > 0 ) {
						this.current_thumb = this.$thumbs.index( $current_thumb );
					} else {
						this.current_thumb = 0;
					}
				}
			},
			update_big_photo: function(/*Number*/ /*id*/){
				var id = arguments.length ? arguments[0] : this.get_current_thumb();  
				this.change_photos(this.thumbs[id].get_big_src());
				this.update_panel(id);
				if ( this.is_master() ) {
					this.show_details( id );
					this.update_features( id );
				}
			},
			update_panel: function(/*Number*/ id) {
				this.unselect_current_thumb();
				this.select_thumb(id);
			},
			unselect_current_thumb: function() {
				var current_thumb = this.thumbs[this.get_current_thumb()];
				if ( current_thumb ) {
					current_thumb.set_state(false);
					current_thumb.update();
				}
			},
			select_thumb: function(/*Number*/ id) {
				this.set_current_thumb(id);
				this.thumbs[id].set_state(true);
				this.thumbs[id].update();
			},
			change_photos: function(/*String*/ photo_src) {
				var $big_photo = this.get_big_photo_elt(),
					duration = this.duration_change_photo,
					current_src = $big_photo.attr( 'src' );
//					console.log( 'new_src != current_src ' + ( new_src != current_src ) );
				if ( photo_src != current_src ) {
//						console.log( 'show big picture // ' + link + ' // [' + thumb.id + ']' );
					$big_photo.stop().animate(
						{ opacity:0 },
						{
							duration: duration,
							complete: function() {
								$big_photo
									.attr("src", photo_src)
									.animate({opacity:1},duration);					
							}
						}
					);
				}
			},
			show_details_work: function ( /*Number*/ id ) {
				var link = this.thumbs[id].get_link();
//				console.log( 'show_details_work() : ' + this.thumbs[id].get_link() );
				if ( link ) this.details_menu.trigger( link );
			},
			show_details: function ( /*Number*/ id ) {
				//empty when page doesn't have details block
			},
			update_features_work: function (  ) {
				var link = this.thumbs[id].get_link();
//				console.log( 'show_details_work() : ' + this.thumbs[id].get_link() );
				if ( link ) this.features.trigger( link );
			},
			update_features: function (  ) {
				//empty when page doesn't have features block
			},
			is_master: function ( /*Boolean setup*/ ) {
				return this._master_mode.set_mode( 'is_master', Boolean( arguments[0] ));
			},
			is_slave: function ( /*Boolean setup*/ ) {
				return this._master_mode.set_mode( 'is_slave', Boolean( arguments[0] ));
			}
		};
	}
	
	function Thumb (/*jQuery*/ Thumb, /*ThumbPanel*/ ThumbPanel, /*Number*/ id){
		return {
			id: id,
			elt: Thumb,
			tp: ThumbPanel,
			literals: options.literals,
			pic_elt: undefined,
			pic_elt_src: {path: undefined, file: undefined},
			selected: undefined,
			link:	undefined,
			init: function() {
				this.pic_elt = $(this.literals.thumb_pic, this.elt);
				this.parse_src();
				this.set_state();
				this.update();
				if ( this.elt[0].tagName == 'A' ) {
//					console.log( "this.elt[0].tagName == 'A' : " + (this.elt[0].tagName == 'A') );
					this.set_link();
				}
			},
			set_link: function () {
				this.link = this.elt.attr( 'href' ).replace( /#/, '' );
//				console.log( this.link );
			},
			get_link: function () {
				return this.link;
			},
			update: function() {
				if (this.get_state()) {
					this.pic_elt.unbind();
					this.select();
					this.unhover();
				} else {
					this.pic_elt.bind("mouseover", {thumb: this}, this.mouseover);
					this.pic_elt.bind("mouseout", {thumb: this}, this.mouseout);
					this.pic_elt.bind("click", {thumb: this}, this.click);
					this.unselect();
				}
			},
			get_id: function() {
				return this.id;
			},
			select: function() {
				this.elt.addClass(this.literals.selected_class);
				this.change_photo(this.get_select_src());
			},
			unselect: function() {
				this.elt.removeClass(this.literals.selected_class);
				this.change_photo(this.get_thumb_src());
			},
			change_photo: function(/*String*/ sNewSrc) {
				var $thumb_photo = this.pic_elt;
				$thumb_photo.attr("src", sNewSrc);
			},
			hover: function(){
				this.elt.addClass(this.literals.hover_class);
			},
			unhover: function(){
				this.elt.removeClass(this.literals.hover_class);
			},
			mouseover: function(/*Event*/ evt) {
				var oThumb = evt.data.thumb;
				oThumb.hover();
			},
			mouseout: function(/*Event*/ evt) {
				var oThumb = evt.data.thumb;
				oThumb.unhover();
			},
			click: function (/*Event*/ evt) {
				evt.preventDefault();
				var oThumb = evt.data.thumb;
				oThumb.tp.is_master( true );
				oThumb.action();
			},
			trigger: function () {
				this.tp.is_slave( true );
				this.action();
			},
			action: function () {
				this.tp.update_big_photo(this.get_id());
			},
			get_pic_src: function() {
				return this.pic_elt_src;
			},
			parse_src: function() {
				var sFileName = this.pic_elt.attr("src").split("/");
				this.pic_elt_src.file = sFileName.pop();
				this.pic_elt_src.path = sFileName.join("/") + "/";
			},
			get_state: function() {
				return this.selected;
			},
			set_state: function(/*Boolean*/ /*state*/) {
				this.selected = arguments.length ? arguments[0] : this.elt.hasClass(this.literals.selected_class);
			},
			get_big_src: function() {
				return this.pic_elt_src.path + this.pic_elt_src.file.replace("_thumb","");
			},
			get_select_src: function() {
				return this.pic_elt_src.path + this.pic_elt_src.file.replace("_thumb","_thumb_s");
			}
			,
			get_thumb_src: function() {
				return this.pic_elt_src.path + this.pic_elt_src.file.replace("_thumb_s","_thumb");
			}
		};
	}
	
	function fixIE6layout() {
		if ($.browser.msie && $.browser.version < 7){
			// colors panel width
			$(".b-cat .b-colors").each(
				function(/*Number*/index) {
					var $color_panel = $(this),
						children = $(".b-color_item", $color_panel),
						parent_padding = 4;
					$color_panel.width(children.size() * children.width() + parent_padding*2);
				}
			);
			
			// blue button
			$(".b-button-wrap .d-sides .d-l").each(
				function() {
					var $button_bg = $(this);
					$button_bg.width($button_bg.parent().width());
				}
			);
		}
	}
	
	function complect_enable ( /*Object*/ options ) {
		var options = new StyleSheetElements( options ),
			$details = $( options.get_class( 'details' ) );
			$menu = $( options.get_class( 'menu' ), $details );
//		console.log( '$menu: ' + $menu.size() );
		$.each( $menu, setup_menu );
		
		function setup_menu ( index ) {
			var oMenu = new DetailsMenu( $details, this, thumb_panels[index], index );
			oMenu.init();
		}
		
		function DetailsMenu ( /*jQuery*/ $details, /*Node*/ $menu, /*ThumbPanel*/ thumb_panel,  /*Number*/ id ) {
			return {
				id: 					id,
				thumb_panel:			thumb_panel,
				$details: 				$details,
				$menu:					$( $menu, $details ),
				$main_frame:			$( options.get_class( 'main_frame' ), $details ),
				features:				undefined,
				menu_items:				[],
				menu_items_links:		[],
				details_items:			[],
				details_links:			[],
				selected_menu_item: 	undefined,
				_mode: 					new ModeController(),
				_master_mode:			new ModeController(),
				duration_main_frame:	800,
				init: function () {
					var _this 				= this;
						$menu_items 		= $( options.get_class( 'menu_item' ), this.$menu ),
						$details_items 		= $( options.get_class( 'details_item' ), this.$details ),
						$features 			= $( options.get_class( 'features' ) ),
						parent_item			= undefined;
					this.is_idle( true );
					this.is_master( true );
					$.each( $details_items, setup_details_item );
					$.each( $features, enable_features_links );
					$.each( $menu_items, setup_menu_item );
					enable_local_links_on_page();
					
					if ( this.thumb_panel ) {
						this.thumb_panel.activate_details_connection( this );
					}
					
//					$.each( this.menu_items, this.menu_items[0].update );
					function setup_menu_item ( index ) {
						var oMenuItem = new DetailsMenuItem( _this, this, index );
						oMenuItem.init();
						_this.menu_items.push( oMenuItem );
						if ( oMenuItem.has_submenu() ) {
							parent_item = oMenuItem;
						}
						if ( oMenuItem.has_parent() && ( oMenuItem.$parent[0] == parent_item.$item[0] ) ) {
							oMenuItem.set_parent( parent_item );
						}
						_this.menu_items_links.push( oMenuItem.link );
					}
					
					function setup_details_item ( index ) {
						var oDetailsItem = new DetailsItem( _this, this, index );
						oDetailsItem.init();
						_this.details_items.push( oDetailsItem );
//						console.log( 'oDetailsItem.link: ' + oDetailsItem.link );
						_this.details_links.push( oDetailsItem.link );
					}
					
					function enable_features_links ( index ) {
						var features = new Features( _this, this, index );
						features.init();
						_this.features = features;
					}
					
					function enable_local_links_on_page () {
						var local_links = $( 'a[href*=#]' ).filter( filter_service_links );
						$.each( local_links, enable_local_links );
						
						function filter_service_links ( index ) {
//							console.log( index + ': ' + $( this ).parents( options.get_class( 'features' ) ).size() );
							var flag =  $( this ).parents( options.get_class( 'features' ) ).size();
							flag |= $( this ).parents( options.get_class( 'menu' ) ).size();
							flag |= $( this ).parents( options.get_class( 'thumb_panel' ) ).size();
							
							return !flag;
						}
						
						function enable_local_links ( index ) {
							
							$( this ).bind(
								{ click: 
									function ( /*Event*/ evt ) {
										evt.preventDefault();
										evt.stopPropagation();
										var details_menu = evt.data.details_menu,
											link = $( this ).attr( 'href' ).replace( /#/, '' );
										details_menu.master_trigger( link );
									}
								},
								{ details_menu: _this }
							);
						}
						
//						console.log( local_links.size() );
					}
				},
				update: function ( /*DetailsMenuItem*/ item ) {
					if ( this.selected_menu_item ) {
//						console.log( 'before :: this.selected_menu_item: ' + this.selected_menu_item.id );
					} else {
//						console.log( 'before :: this.selected_menu_item: ' + this.selected_menu_item );
					}
//					console.log( 'before :: this._mode: ' + this._mode.get_mode() );
//					console.log( 'before :: this._mode: ' + this._mode.get_mode() );
					if ( item.is_selected() ) {
						var previous_item = this.selected_menu_item;
						this.selected_menu_item = item;
						if ( this.is_idle() ) {
							if ( item.has_parent() ) {
								item.parentize();
								this.is_subitem_selected( true );
							} else {
								this.is_item_selected( true );
							}
						} else if ( this.is_item_selected() ) {
							if ( item.has_parent() ) {
								if ( previous_item.$item[0] == item.$parent[0] ) {
									previous_item.parentize();
								} else {
									previous_item.unselect();
									item.parent.parentize();
									item.select();
								}
								this.is_subitem_selected( true );
							} else {
								previous_item.unselect();
								this.is_item_selected( true );
							}
						} else if ( this.is_subitem_selected() ) {
							if ( item.has_no_parent() ) {
								if ( previous_item.$parent[0] != item.$item[0] ) {
									previous_item.parent.unselect();
									previous_item.unselect();
								} else {
									previous_item.unselect();
								}
								this.is_item_selected( true );
								
							} else if ( item.has_parent() ) {
								if ( previous_item.$parent[0] != item.$parent[0] ) {
									previous_item.parent.unselect();
								}
								previous_item.unselect();
								this.selected_menu_item = item;
								this.is_subitem_selected( true );
							}
						}
						this.update_details( previous_item, item );
						if ( this.is_master() ) {
							if ( this.thumb_panel ) this.update_big_photo( item );
							if ( this.features ) this.features.trigger( item.get_link() );
						}
					}
//					console.log( 'after :: this._mode: ' + this._mode.get_mode() );
					if ( this.selected_menu_item ) {
//						console.log( 'after :: this.selected_menu_item: ' + this.selected_menu_item.id );
					} else {
//						console.log( 'after :: this.selected_menu_item: ' + this.selected_menu_item );
					}
				},
				update_mainframe_height: function ( /*DetailsItem*/ details ) {
//					console.log( 'update_mainframe_height()' );
					var details_height = details.get_detail_height();
//					console.log( 'details_height: ' + details_height );
//					console.log( 'this.$main_frame: ' + this.$main_frame.size() );
					this.$main_frame.stop().animate(
						{ height: details_height },
						{ 
							duration: this.duration_main_frame,
							easing: 'easeInOutQuad'
						}
					);
				},
				update_details: function ( /*DetailsMenuItem*/ previous_item, /*DetailsMenuItem*/ new_item ) {
					var	previous_detail, new_detail;
					if ( previous_item ) {
						previous_detail = this.get_details_by_link( previous_item.link );
						previous_detail.hide();
					}
					new_detail = this.get_details_by_link( new_item.link );
					new_detail.show();
					this.update_mainframe_height( new_detail );
				},
				update_big_photo: function ( /*DetailsMenuItem*/ new_item ) {
//					console.log( 'update_big_photo(): ' + new_item.link );
					var link = new_item.get_link(),
						big_pic_exists = this.thumb_panel.big_pic_exists_by_link( link );
					if ( !big_pic_exists ) {
						if ( new_item.has_parent() ) {
							this.update_big_photo( new_item.parent );
						}
					} else {
						this.thumb_panel.trigger( link );
					}
				},
				get_details_by_link: function ( /*String*/ link ) {
					for ( var i = 0, l = this.details_links.length; i < l; i++) {
						if ( this.details_links[i] == link ) return this.details_items[i];
					}
//					console.log( 'get_details_by_link() :: ' + link + ' : not found()' );
					return false;
				},
				get_menu_item_by_link: function ( /*String*/ link ) {
					for ( var i = 0, l = this.menu_items_links.length; i < l; i++) {
						if ( this.menu_items_links[i] == link ) return this.menu_items[i];
					}
//					console.log( 'get_menu_item_by_link() :: ' + link + ' : not found()' );
					return false;
				},
				trigger: function ( /*String*/ link ) {
					var menu_item = this.get_menu_item_by_link( link );
					if ( menu_item && ( menu_item.is_unselected() || menu_item.is_parent() ) ) {
						menu_item.trigger();
//						console.log( 'DetailsMenu.trigger() : ' + link );
					}
				},
				master_trigger: function ( /*String*/ link ) {
					var menu_item = this.get_menu_item_by_link( link );
					if ( menu_item && ( menu_item.is_unselected() || menu_item.is_parent() ) ) {
						menu_item.master_trigger();
//						console.log( 'DetailsMenu.trigger() : ' + link );
					}
				},
				is_idle: function ( /*Boolean setup*/ ) {
					return this._mode.set_mode( 'is_idle', Boolean( arguments[0] ));
				},
				is_item_selected: function ( /*Boolean setup*/ ) {
					return this._mode.set_mode( 'is_item_selected', Boolean( arguments[0] ));
				},
				is_subitem_selected: function ( /*Boolean setup*/ ) {
					return this._mode.set_mode( 'is_subitem_selected', Boolean( arguments[0] ));
				},
				is_master: function ( /*Boolean setup*/ ) {
					return this._master_mode.set_mode( 'is_master', Boolean( arguments[0] ));
				},
				is_slave: function ( /*Boolean setup*/ ) {
					return this._master_mode.set_mode( 'is_slave', Boolean( arguments[0] ));
				}
			};
		}
		
		function DetailsMenuItem ( /*DetailsMenu*/ menu, /*Node*/ item, /*Number*/ id ) {
			return {
				id: 					id,
				menu: 					menu,
				link:					undefined,
				$item: 					$( item, menu.$menu ),
				$link_item:				$( item, menu.$menu ).children( options.get_class( 'menu_link' ) ),
				$submenu:				$( options.get_class( 'submenu' ), item ),
				$subitems:				$( options.get_class( 'menu_item' ), item ),
				$parent:				$( item, menu.$men ).parents( options.get_class( 'menu_item' ) ),
				parent:					undefined,
				children:				[],
				submenu_height:			0,
				_select_mode: 			new ModeController(),
				_submenu_mode: 			new ModeController(),
				_submenu_state_mode: 	new ModeController(),
				_parent_mode: 			new ModeController(),
				duration_submenu_open:	500,
				duration_submenu_close:	800,
				duration_update_height:	300,
				submenu_margin_top:		'.3em',
				init: function () {
//					console.log( 'DetailsMenuItem[' + this.id + '].init()' );
					if ( this.$submenu.size() ) {
						this.has_submenu( true );
						this.submenu_height = this.calculate_submenu_height();
						this.submenu_is_closed( true );
//						console.log( 'this.$submenu.height(): ' + this.$submenu.height() );

//						console.log( 'this.$submenu.height(): ' + submenu_height );
					} else {
						this.has_no_submenu( true ); 
					}
					
					if ( this.$parent.size() ) 	this.has_parent( true );
					else this.has_no_parent( true );
					
					if ( this.$item.hasClass( options.get_name( 'menu_item_selected' ) ) ) {
						this.select();
					} else {
						this.unselect();
					}
					
					this.set_link();
//					console.log( 'DetailsMenuItem[' + this.id + '].link : ' + this.link );
					this.update();
//					console.log( 'DetailsMenuItem[' + this.id + '].has_submenu: ' + this.has_submenu() );
//					console.log( 'DetailsMenuItem[' + this.id + '].has_parent: ' + this.has_parent() );
				},
				set_parent: function ( /*DetailsMenuItem*/ parent) {
					this.parent = parent;
					this.parent.add_child( this );
				},
				add_child: function ( /*DetailsMenuItem*/ child ) {
					this.children.push( child );
				},
				set_link: function () {
					this.link = this.$link_item.attr( 'href' ).replace(/#/,''); 
				},
				get_link: function () {
					return this.link;
				},
				calculate_submenu_height: function () {
					var submenu_height = 0;
					this.$subitems.each( 
						function ( index ) {
							var $subitem = $( this );
							submenu_height += $( this ).height();
							submenu_height += parseInt( $subitem.css( 'marginTop' ) );
							submenu_height += parseInt( $subitem.css( 'marginBottom' ) );
							submenu_height += parseInt( $subitem.css( 'paddingTop' ) );
							submenu_height += parseInt( $subitem.css( 'paddingBottom' ) );
						}
					);
					return submenu_height;
				},
				idle: function ( /*Event*/ evt ) {
					evt.preventDefault();
					evt.stopPropagation();
				},
				click: function ( /*Event*/ evt ) {
					var controller = evt.data.controller;
					evt.preventDefault();
					evt.stopPropagation();
					controller.menu.is_master( true );
					controller.action();
				},
				trigger: function () {
					this.menu.is_slave( true );
					this.action( this );
				},
				master_trigger: function () {
					this.$link_item.trigger( 'click' );
				},
				action: function () {
					if ( this.is_selected() ) {
						this.unselect();
					} else {
						this.select();
					}
					this.update( this );
//					console.log( 'DetailsMenuItem.trigger() : ' + this.id );
				},
				select: function () {
//					console.log( 'DetailsMenuItem[' + this.id + '].select()' );
					this.is_selected( true );
					this.enable_click( false );
					this.$item.addClass( options.get_name( 'menu_item_selected' ) );
					this.$item.removeClass( options.get_name( 'menu_item_parent' ) );
					if ( this.has_submenu() ) {
						this.open_submenu();
					}
				},
				unselect: function () {
//					console.log( 'DetailsMenuItem[' + this.id + '].unselect()' );
					this.disable_resize();
					this.is_unselected( true );
					this.enable_click( true );
					this.$item.removeClass( options.get_name( 'menu_item_selected' ) );
					this.$item.removeClass( options.get_name( 'menu_item_parent' ) );
					if ( this.has_submenu()	) {
						this.close_submenu();
					}
				},
				parentize: function () {
					this.is_parent( true );
					this.$item.removeClass( options.get_name( 'menu_item_selected' ) );
					this.$item.addClass( options.get_name( 'menu_item_parent' ) );
					this.enable_click( true );
					if ( this.has_submenu() && this.submenu_is_closed() ) {
						this.open_submenu();
					}
				},
				open_submenu: function () {
					var _this = this;
					this.$submenu.stop().animate(
						{ 
							height: this.submenu_height,
							marginTop: this.submenu_margin_top
						},
						{
							duration: this.duration_submenu_open,
							easing: "easeInOutQuad",
							complete: function () {
								_this.enable_resize();
								_this.submenu_is_open( true );
//								$.scrollTo( 
//									options.get_class( 'main_frame' ), 
//									500, 
//									{ 
//										easing: 'easeInOutQuad', 
//										onAfter: after_scroll
//									}
//								);
//								
//								function after_scroll () {
////									console.log( 'scroll' );
//								}
							}
						}
					);
				},
				close_submenu: function () {
					var _this = this;
					this.$submenu.stop().animate(
						{ height: 0	},
						{
							duration: this.duration_submenu_close,
							easing:	"easeInOutQuad",
							complete: function () {
								$( this	).css( { marginTop:	0 }	);
								_this.submenu_is_closed( true );
							}	
						}
					);
				},
				enable_click: function ( /*Boolean*/ flag ) {
					this.$link_item.unbind( 'click.details' );
					if ( flag ) {
						this.$link_item.bind( 'click.details', { controller: this }, this.click );				
					} else {
						this.$link_item.bind( 'click.details', { controller: this }, this.idle );		
					}
				},
				update: function ( /*DetailsMenuItem*/ item ) {
//					console.log( 'DetailsMenuItem[' + this.id + ']._mode : ' + this._select_mode.get_mode() );
					var item = item ? item : this;
					this.menu.update( item );
				},
				enable_resize: function () {
//					if ( this.has_no_submenu() ) return;
//					console.log( 'enable_resize' );
					$.each( this.children, enable_resize );
					
					function enable_resize ( index ) {
						this.$item.bind(
							{ resize: $.throttle( 150, this.update_height ) },
							{ controller: this }
						);
					}
				},
				disable_resize: function () {
//					if ( this.has_no_submenu() ) return;
//					console.log( 'disable_resize' );
					$.each( this.children, disable_resize );
					
					function disable_resize ( index ) {
						this.$item.unbind( 'resize'	);
					}
				},
				update_height: function ( /*Event*/ evt ) {
					var controller = evt.data.controller,
						current_height = controller.parent.submenu_height,
						new_height = controller.parent.calculate_submenu_height();
					if ( new_height != current_height ) {
						controller.parent.submenu_height = new_height;
//						console.log( 'DetailsMenuItem[' + controller.id + '].update_height()' );
						controller.parent.$submenu.stop().animate(
							{ height: new_height },
							{	
								duration: this.duration_update_height,
								easing: 'easeInOutQuad'
							}
						);
					}
				},
				is_selected: function ( /*Boolean setup*/ ) {
					return this._select_mode.set_mode( 'is_selected', Boolean( arguments[0] ));
				},
				is_unselected: function ( /*Boolean setup*/ ) {
					return this._select_mode.set_mode( 'is_unselected', Boolean( arguments[0] ));
				},
				is_parent: function ( /*Boolean setup*/ ) {
					return this._select_mode.set_mode( 'is_parent', Boolean( arguments[0] ));
				},
				has_submenu: function ( /*Boolean setup*/ ) {
					return this._submenu_mode.set_mode( 'has_submenu', Boolean( arguments[0] ));
				},
				has_no_submenu: function ( /*Boolean setup*/ ) {
					return this._submenu_mode.set_mode( 'has_no_submenu', Boolean( arguments[0] ));
				},
				has_parent: function ( /*Boolean setup*/ ) {
					return this._parent_mode.set_mode( 'has_parent', Boolean( arguments[0] ));
				},
				has_no_parent: function ( /*Boolean setup*/ ) {
					return this._parent_mode.set_mode( 'has_no_parent', Boolean( arguments[0] ));
				},
				submenu_is_open: function ( /*Boolean setup*/ ) {
					return this._submenu_state_mode.set_mode( 'submenu_is_open', Boolean( arguments[0] ));
				},
				submenu_is_closed: function ( /*Boolean setup*/ ) {
					return this._submenu_state_mode.set_mode( 'submenu_is_closed', Boolean( arguments[0] ));
				}
			};
		}
		
		function DetailsItem ( /*DetailsMenu*/ menu, /*Node*/ item, /*Number*/ id ) {
			return {
				id: 				id,
				link: 				item.id,
				menu: 				menu,
				$item: 				$( item, menu.$details ),
				duration_change:	500,
				init: function () {
//					console.log( 'DetailsItem[' + this.id + '].init()' );
//					console.log( 'DetailsItem[' + this.id + '].link : ' + this.link );
					this.$item.css( { opacity: 0 } );
					
					if ( $.browser.msie ) {
						this.change = this.change_ie;
						this.$item.css( { visibility: 'hidden' } );
					} else {
						this.$item.css( { display: 'none' } );
					}
				},
				show: function () {
//					console.log( 'DetailsItem[' + this.id + '].show() :: ' + this.link);
					this.$item.addClass( options.get_name( 'details_item_selected' ) );
					this.change( true );
				},
				hide: function () {
//					console.log( 'DetailsItem[' + this.id + '].hide() :: ' + this.link);
					this.$item.removeClass( options.get_name( 'details_item_selected' ) );
					this.change();
				},
				change: function ( /*Boolean*/ show ) {
					var _this = this,
						new_opacity = 0;
					if ( show ) {
						this.$item.css( { display: 'block', opacity: 0 } );
						new_opacity = 1;
					}
					this.$item.stop().animate(
						{ opacity: new_opacity },
						{
							duration: this.duration_change,
							easing: 'easeInOutQuad',
							complete: function () {
								if ( !show ) {
									_this.$item.css( { display: 'none' } );
								}
							}
						}
					);
				},
				change_ie: function ( /*Boolean*/ show ) {
					var _this = this,
						new_opacity = 0;
					if ( show ) {
						this.$item.css( { visibility: 'visible', opacity: 0 } );
						new_opacity = 1;
					}
					this.$item.stop().animate(
						{ opacity: new_opacity },
						{
							duration: this.duration_change,
							easing: 'easeInOutQuad',
							complete: function () {
								if ( !show ) {
									_this.$item.css( { visibility: 'hidden' } );
								}
							}
						}
					);
				},
				get_detail_height: function () {
//					console.log( 'DetailsItem[' + this.id + '].get_detail_height()' );
					return this.$item.height();
				}
			};
		}
		
		function Features ( /*DetailsMenu*/ menu, /*Node*/ $features, /*Number*/ id ) {
			return {
				id: 				id,
				menu: 				menu,
				$features: 			$( $features ),
				$features_items:	$( options.get_class( 'features_item' ), $features ),
				features_items:		[],
				selected_group:		[],
				_master_mode:		new ModeController(),
				init: function () {
//					console.log( 'Features.init()' );
					var _this = this;
//					console.log( 'this.$features_items.size() : ' + this.$features_items.size() );
					$.each( this.$features_items, enable_feature_items );
					
					function enable_feature_items ( index ) {
						var oItem = new FeaturesItem( _this, this, index );
						oItem.init();
						_this.features_items.push( oItem );
					}
					
					if ( this.menu.thumb_panel ) {
						this.menu.thumb_panel.activate_features_connection( this );
					}
				},
				update: function ( /*FeaturesItem*/ item ) {
//					console.log( 'Features.update(' + item.id + ')' );
					var details_menu = this.menu,
						link = item.get_link();
						
					this.select_group( link );
					if ( this.is_master() ) {
						details_menu.trigger( link );
						link = check_big_pic_link( details_menu.get_menu_item_by_link( link ) );
						details_menu.thumb_panel.trigger( link );
					}
					
					function check_big_pic_link  ( /*DetailsMenuItem*/ item ) {
						var link = item.link,
							big_pic_exists = details_menu.thumb_panel.big_pic_exists_by_link( link );
						if ( !big_pic_exists ) {
							if ( item.has_parent() ) return check_big_pic_link( item.parent );
							else return undefined;
						} else {
							return link;
						}
					}
				},
				trigger: function ( /*String*/ link ) {
					var item = this.get_item_by_link( link );
//					console.log( 'item: ' + item );
					if ( item ) {
						item.trigger();
//						console.log( 'Features.trigger( "' + link + '" )' );
					} else {
						this.unselect_previous_group();
					}
				},
				get_item_by_link: function ( /*String*/ link ) {
					var features_items = this.features_items,
						item;
					for (var i = 0, l = features_items.length; i < l ; i++) {
						item = features_items[i];
						if ( item.get_link() == link ) {
							return item;
						}
					}
//					console.log( 'Features.get_item_by_link( "' + link + '" ) was not found.' );
					return false;
				},
				select_group: function ( /*String*/ link ) {
					this.unselect_previous_group();
					var features_items = this.features_items;
					for ( var i = 0, l = features_items.length; i < l; i++ ) {
						var item = features_items[i];
						if ( item.get_link() == link ) {
							this.selected_group.push( item );
							item.select();
						}
					}						
				},
				unselect_previous_group: function () {
					var features_items = this.selected_group;
					for (var i = 0; i < features_items.length; i++) {
						features_items[i].unselect();
					}
					features_items = [];
//					console.log( 'features_items.length : ' + features_items.length );
				},
				is_master: function ( /*Boolean setup*/ ) {
					return this._master_mode.set_mode( 'is_master', Boolean( arguments[0] ));
				},
				is_slave: function ( /*Boolean setup*/ ) {
					return this._master_mode.set_mode( 'is_slave', Boolean( arguments[0] ));
				}
			};
		}
		
		/*

		
		 * */
		
		function FeaturesItem ( /*Features*/ features, /*Node*/ item, /*Number*/ id ) {
			return {
				id: 			id,
				features: 		features,
				$item: 			$( item, features.$features ),
				link:			undefined,
				_mode:			new ModeController(),
				init: function () {
//					console.log( 'FeaturesItem[' + this.id + ']' );
					this.set_link();
					this.is_unselected( true );
					this.$item.bind(
						{ click: this.click },
						{ controller: this }
					);
				},
				set_link: function () {
					this.link = this.$item.attr( 'href' ).replace( /#/, '' );
				},
				get_link: function () {
					return this.link;
				},
				click: function ( /*Event*/ evt ) {
					evt.preventDefault();
					evt.stopPropagation();
					var controller = evt.data.controller;
					controller.features.is_master( true );
					controller.action();
//					console.log( 'FeaturesItem[' + controller.id + '].click()' );
				},
				trigger: function () {
					this.features.is_slave( true );
					this.action();
				},
				action: function () {
					if ( this.is_unselected() ) {
						this.features.update( this );
					}
				},
				select: function () {
					this.$item.addClass( options.get_name( 'features_item_selected' ) );
					this.is_selected( true );
				},
				unselect: function () {
					this.$item.removeClass( options.get_name( 'features_item_selected' ) );
					this.is_unselected( true );
				},
				is_selected: function ( /*Boolean setup*/ ) {
					return this._mode.set_mode( 'is_selected', Boolean( arguments[0] ));
				},
				is_unselected: function ( /*Boolean setup*/ ) {
					return this._mode.set_mode( 'is_unselected', Boolean( arguments[0] ));
				}
			};
		}
	}

	function enable_topmenu ( /*Object*/ options ) {
		var options = new StyleSheetElements( options ),
			$topmenu = $( options.get_class( 'topmenu' ) ),
			$selected_items = $( options.get_class( 'topmenu_item' ) + '[class*=' + options.get_name( 'item_selected_postfix' ) + ']', $topmenu );
		
//		$selected_items.each( disable_link ); 
	}
	
	function disable_link ( index ) {
		$( this ).click( function( /*Event*/ evt ) { evt.preventDefault(); } );
	}
	
	function enable_tabs( /*Object*/ options ) {
		var options = new StyleSheetElements( options ),
			$tabs = $( options.get_class( 'tabs' ) );
		$.each( $tabs, setup_tabs );
		function setup_tabs( index, item ) {
//			console.log( 'tabs_enabled' );
			var is_local = $( this ).attr( 'class' ).match( options.get_name( 'local_tabs' ) );
			
			if ( is_local ) {
				var edge_mode = $( item ).hasClass( options.get_name( "edge_mode" ) ),
					oTabContent = new TabContent( this, index ),
					oTabPanel = new TabPanel( this, oTabContent, index, edge_mode );
				oTabContent.init();
				oTabPanel.init();
			} else {
				var $selected_tabs = $( options.get_class( 'tab_selected' ), this );
//				$selected_tabs.each( disable_link );
			}
		}
		
		function TabPanel( /*DOM*/ tabs, /*TabContent*/ content, /*Number*/ id, /*Boolean*/ edge_mode ) {
			return {
				id: 		id,
				$tabs: 		$( tabs ),
				$panel: 	undefined,
				$tab_items: undefined,
				tab_items: 	[],
				content: 	content,
				selected: 	undefined,
				init: function () {
					var _this = this,
						last_index;
					this.$panel = $( options.get_class( 'tabs_panel' ), this.$tabs );
					this.$tab_items = $( options.get_class( 'tab_item' ), this.$panel );
					last_index = this.$tab_items.size() - 1;
					$.each( this.$tab_items, setup_tab_item );
//					console.log( 'panel: ' + this.id );
					select_current_tab();
					
					function setup_tab_item( index, item, items ) {
						var position = ! edge_mode ? 0 : ( (index == 0 ) ? -1 : ( index == last_index ? 1 : 0 ) ),
							oTabItem = new TabItem( this, _this, index, position );
						oTabItem.init();
						if( oTabItem.is_selected() ) {
							_this.selected = oTabItem;
							_this.update( oTabItem );
						}
						_this.tab_items.push( oTabItem );
					}
					
					function select_current_tab () {
						var has_selected_tab = $( options.get_class( 'tab_selected' ) , _this.$panel).size() > 0;
//						console.log( 'has_selected_tab: ' + has_selected_tab );
						if ( has_selected_tab ) {
							return;
						} else {
//							var local_address = location.href.match( /[\w\-_\.,\+\?\=]+\/?$/);
							var local_address = location.pathname + location.search + location.hash;
//							console.log( 'local_address: ' + local_address );
							if ( local_address.length > 0 ) {
								var $selected_tab = $( options.get_class( 'tab_item' ) + '[href$=' + local_address + ']' , _this.$panel );
								if ( $selected_tab.size() > 0 ) {
									var index = _this.$tab_items.index( $selected_tab );
//									console.log( '$selected_tab : ' + $selected_tab.size() );
//									console.log( 'index : ' + index );
									_this.tab_items[index].click();
								}
							}
						}
					}
				},
				get_selected: function () { return this.$selected; },
				set_selected: function ( /*TabItem*/ tab_item ) { this.selected = tab_item; },
				update: function ( /*TabItem*/ tab_item ) {
//					console.log( 'update: ' + tab_item );
					if ( this.selected ) this.selected.unselect();
					this.selected = tab_item;
					tab_item.select();
					this.content.show( this.selected.get_id() );
				}
			};
		}
		
		function TabItem( /*DOM*/ tab_item, /*TabPanel*/ panel, /*Number*/ id, /*Number*/ position ) {
			return {
				id: 		id,
				node_id:	tab_item.id.replace( options.get_name( 'tab_id_prefix' ), '' ),
				panel: 		panel,
				$tab_item: 	$( tab_item ),
				selected: 	undefined,
				selected_class: position == 0 ? options.get_name( 'tab_selected' ) : ( position == -1 ? options.get_name( 'first_selected' ) : options.get_name( 'last_selected' )  ),
				unselected_class: '',
				init: function () {
//					console.log( 'node_id: ' + this.node_id );
					this.$tab_item.bind(  'click', { _this: this }, click_handler );
					this.selected = this.$tab_item.hasClass( this.selected_class );
					this.unselected_class = position == 0 ? '' : this.selected_class.replace( /_selected/, '' );
					function click_handler( /*Event*/ evt ) {
						evt.preventDefault();
						var _this = evt.data._this;
						if( !_this.is_selected() ) _this.panel.update(_this );
					}
					
					if ( $.browser.msie && $.browser.version < 7 )
						this.fix_decor = this.fix_ie6;
				},
				is_selected: function () { return this.selected; },
				select: function () {
//					console.log( this.id + ': select()' );
					this.$tab_item.addClass( this.selected_class );
					this.$tab_item.removeClass( this.unselected_class );
					this.selected = true;
					this.fix_decor();
				},
				unselect: function () {
//					console.log( this.id + ': unselect()' );
					this.$tab_item.removeClass( this.selected_class );
					this.$tab_item.addClass( this.unselected_class );
					this.selected = false;
					this.fix_decor();
				},
				get_id: function () {
					if (this.node_id) 
						return this.node_id;
					else
						return this.id;
				},
				click: function () {
					this.$tab_item.trigger( 'click' );
				},
				fix_decor: function () {},
				fix_ie6: function () {
					var $decor = $( options.get_class( 'tab_decor_l' ), this.$tab_item );
					$decor.width( $decor.parent().outerWidth() ); 
				}
			};
		}
		
		function TabContent( /*DOM*/ tabs, /*Number*/ id ) {
			return {
				id: 			id,
				$tabs: 			$( tabs ),
				$content: 		undefined,
				$content_items: undefined,
				selected: 		false,
				selected_class: options.get_name( 'content_selected' ),
				init: function () {
					this.$content = $( options.get_class( 'content' ), this.$tabs );
					this.$content_items = $( options.get_class( 'content_item' ), this.$content );
					this.selected = $( options.get_class( 'content_selected' ), this.$content );
				},
				show: function ( /*Number*/ id ) {
//					console.log( 'content_item[' + id + '] is selected' );
					var $selected;
					if ( id === +id )
						$selected = this.get_item_by_order( id );
					else
						$selected = this.get_item_by_node_id( id );
					this._hide_deselected();
//					console.log( '$selected: ' + $selected );
					$selected.addClass( this.selected_class );
					this.selected = $selected;
				},
				get_item_by_node_id: function ( /*String*/ id ) {
					id = options.get_id( 'content_id_prefix' ) + id;
//					console.log( 'get_item_by_node_id: ' + $( id, this.$content ).size() );
					return $( id, this.$content );
				},
				get_item_by_order: function ( /*Number*/ id ) {
					return $( this.$content_items[id] );
				},
				_hide_deselected: function () {
					this.selected.removeClass( this.selected_class );
					this.selected = null;
				}
			};
		}
	}

	function enable_cross_link_in_catalog_index ( options ) {
		var options = new StyleSheetElements( options ),
			$items = $( options.get_class( 'item' ) ),
			items = [];
//		window.console && console.log( '$items.size(): ' + $items.size() );
		if ( $items.size() == 0 ) return;
		$.each( $items, enable_link );

		function enable_link ( /*Number*/ index ) {
//			window.console && console.log( 'index: ' + index );
			var item = new SmallItem( this, index );
			items.push( item );
		}

		function SmallItem ( /*jQuery*/ elt, /*Number*/ id ) {
			var img = $( options.get_class( 'img' ), elt ),
				header = $( options.get_class( 'header' ), elt ).children( 'A' ),
				img_link = new Connector( img, header, 'img' ),
				header_link = new Connector( header, img, 'header' );

			return {
				$elt: 	$( elt ),
				id: 	id,
				img:	img_link,
				header:	header_link
			}
		}

		function Connector ( /*jQuery*/ elt, /*jQuery*/ link, /*String*/ prefix ) {
			var highlight_class = options.get_name( prefix + '_highlight_class' );

			elt.bind( 'mouseenter.connector', handler)
			   .bind( 'mouseleave.connector', handler);

			function handler ( /*Event*/ evt, /*Boolean*/ is_triggered ) {
//				window.console && console.log( 'mouseenter: ' + evt.target);
//				window.console && console.log( 'is_triggered: ' + is_triggered );
//				window.console && console.log( 'type: ' + evt.type );
				var event_name = evt.type + '.connector';
				if ( is_triggered ) {
					elt.toggleClass( highlight_class );
				} else {
					link.trigger( event_name, [ true ] );
				}
			}

			return {
				elt: elt,
				link: link
			}
		}
	}
});


/*	ExternalCall
 	============
  	externals = new ExternalCall( 
  		[
  			{
			 	target:	 object,
			 	method:	 string,
			 	args:	 object,
			 	type:	 string		
			}, 
			{...} 
		]
	);
	externals.add( 
		[
			{
			 	target:	 object,
			 	method:	 string,
			 	args:	 object,
			 	type:	 string		
			} 
		]
	);
	@call: externals.call( type );
 *	============	*/
function ExternalCall ( /*Array*/ literal_calls_array ) {
	return {
		calls: literal_calls_array,
		has: function ( /*Object*/ prop ) {
			for (var i = 0; i < this.calls.length; i++ ) {
				if ( this.calls[i].type == prop ) 
					return true;
			}
			return false;
		},
		call: function ( /*Object*/ prop ) {
			$.each( this.calls, execute );

			function execute ( index ) {
				if ( this.type == prop ) {
					this.target[this.method].call( this.target, this.args );
//					console.log( 'index: ' + index );
				}
			}
		},
		add: function ( /*Array*/ literal ) {
			this.calls = this.calls.concat( literal );
		},
		clear: function () {
			this.calls = [];
		}
	};
}

/*	ModeController
	==============
	flag_yes: function ( /Boolean setup/ ) {
		return this._custom_mode.set_mode( 'flag_yes', Boolean( arguments[0] ));
	}
	flag_no: function ( /Boolean setup/ ) {
		return this._custom_mode.set_mode( 'flag_no', Boolean( arguments[0] ));
	}			
 
 	@set: 	flag_yes( true );
 	@check: flag_yes();			@returns Boolean
 * 	==============	*/
function ModeController() {
	return {
		_mode: undefined,
		set_mode: function ( /*String*/ type, /*Boolean*/ setup ) {
			if (setup ) {
				this._mode = type;
				return this._mode;
			} else { return this._mode == type; }
		},
		get_mode: function () {
			return this._mode;
		}
	};
}

/*	StyleSheetElements()
 * 	====================	*/
function StyleSheetElements ( /*Object*/ hash ) {
	return	{
		literals: hash,
		get_query: function ( /*String*/ query, prefix, type ) {
			if( this.literals[query] ) return prefix + this.literals[query];
			else return console.log( '"' + query + '"doesn\'t exist in options.literals // ' + type );
		},
		get_name: function ( /*String*/ query ) {
			return this.get_query( query, '', 'get_name' );
		},
		get_class: function ( /*String*/ query ) {
			return this.get_query( query, '.', 'get_class' );
		},
		get_id: function ( /*String*/ query ) {
			return this.get_query( query, '#', 'get_id' );
		}
	};
}


/*
 * jQuery plugins
 */

/**
 * jQuery.Preload - Multifunctional preloader
 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com
 * Dual licensed under MIT and GPL.
 * Date: 3/25/2009
 * @author Ariel Flesler
 * @version 1.0.8
 */
;(function($){var h=$.preload=function(c,d){if(c.split)c=$(c);d=$.extend({},h.defaults,d);var f=$.map(c,function(a){if(!a)return;if(a.split)return d.base+a+d.ext;var b=a.src||a.href;if(typeof d.placeholder=='string'&&a.src)a.src=d.placeholder;if(b&&d.find)b=b.replace(d.find,d.replace);return b||null}),data={loaded:0,failed:0,next:0,done:0,total:f.length};if(!data.total)return finish();var g=$(Array(d.threshold+1).join('<img/>')).load(handler).error(handler).bind('abort',handler).each(fetch);function handler(e){data.element=this;data.found=e.type=='load';data.image=this.src;data.index=this.index;var a=data.original=c[this.index];data[data.found?'loaded':'failed']++;data.done++;if(d.enforceCache)h.cache.push($('<img/>').attr('src',data.image)[0]);if(d.placeholder&&a.src)a.src=data.found?data.image:d.notFound||a.src;if(d.onComplete)d.onComplete(data);if(data.done<data.total)fetch(0,this);else{if(g&&g.unbind)g.unbind('load').unbind('error').unbind('abort');g=null;finish()}};function fetch(i,a,b){if(a.attachEvent&&data.next&&data.next%h.gap==0&&!b){setTimeout(function(){fetch(i,a,1)},0);return!1}if(data.next==data.total)return!1;a.index=data.next;a.src=f[data.next++];if(d.onRequest){data.index=a.index;data.element=a;data.image=a.src;data.original=c[data.next-1];d.onRequest(data)}};function finish(){if(d.onFinish)d.onFinish(data)}};h.gap=14;h.cache=[];h.defaults={threshold:2,base:'',ext:'',replace:''};$.fn.preload=function(a){h(this,a);return this}})(jQuery);

/**
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
*/

jQuery.easing.jswing=jQuery.easing.swing;jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,f,a,h,g){return jQuery.easing[jQuery.easing.def](e,f,a,h,g)},easeInQuad:function(e,f,a,h,g){return h*(f/=g)*f+a},easeOutQuad:function(e,f,a,h,g){return -h*(f/=g)*(f-2)+a},easeInOutQuad:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f+a}return -h/2*((--f)*(f-2)-1)+a},easeInCubic:function(e,f,a,h,g){return h*(f/=g)*f*f+a},easeOutCubic:function(e,f,a,h,g){return h*((f=f/g-1)*f*f+1)+a},easeInOutCubic:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f+a}return h/2*((f-=2)*f*f+2)+a},easeInQuart:function(e,f,a,h,g){return h*(f/=g)*f*f*f+a},easeOutQuart:function(e,f,a,h,g){return -h*((f=f/g-1)*f*f*f-1)+a},easeInOutQuart:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f+a}return -h/2*((f-=2)*f*f*f-2)+a},easeInQuint:function(e,f,a,h,g){return h*(f/=g)*f*f*f*f+a},easeOutQuint:function(e,f,a,h,g){return h*((f=f/g-1)*f*f*f*f+1)+a},easeInOutQuint:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+a}return h/2*((f-=2)*f*f*f*f+2)+a},easeInSine:function(e,f,a,h,g){return -h*Math.cos(f/g*(Math.PI/2))+h+a},easeOutSine:function(e,f,a,h,g){return h*Math.sin(f/g*(Math.PI/2))+a},easeInOutSine:function(e,f,a,h,g){return -h/2*(Math.cos(Math.PI*f/g)-1)+a},easeInExpo:function(e,f,a,h,g){return(f==0)?a:h*Math.pow(2,10*(f/g-1))+a},easeOutExpo:function(e,f,a,h,g){return(f==g)?a+h:h*(-Math.pow(2,-10*f/g)+1)+a},easeInOutExpo:function(e,f,a,h,g){if(f==0){return a}if(f==g){return a+h}if((f/=g/2)<1){return h/2*Math.pow(2,10*(f-1))+a}return h/2*(-Math.pow(2,-10*--f)+2)+a},easeInCirc:function(e,f,a,h,g){return -h*(Math.sqrt(1-(f/=g)*f)-1)+a},easeOutCirc:function(e,f,a,h,g){return h*Math.sqrt(1-(f=f/g-1)*f)+a},easeInOutCirc:function(e,f,a,h,g){if((f/=g/2)<1){return -h/2*(Math.sqrt(1-f*f)-1)+a}return h/2*(Math.sqrt(1-(f-=2)*f)+1)+a},easeInElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return -(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e},easeOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return g*Math.pow(2,-10*h)*Math.sin((h*k-i)*(2*Math.PI)/j)+l+e},easeInOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k/2)==2){return e+l}if(!j){j=k*(0.3*1.5)}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}if(h<1){return -0.5*(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e}return g*Math.pow(2,-10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j)*0.5+l+e},easeInBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*(f/=h)*f*((g+1)*f-g)+a},easeOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*((f=f/h-1)*f*((g+1)*f+g)+1)+a},easeInOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}if((f/=h/2)<1){return i/2*(f*f*(((g*=(1.525))+1)*f-g))+a}return i/2*((f-=2)*f*(((g*=(1.525))+1)*f+g)+2)+a},easeInBounce:function(e,f,a,h,g){return h-jQuery.easing.easeOutBounce(e,g-f,0,h,g)+a},easeOutBounce:function(e,f,a,h,g){if((f/=g)<(1/2.75)){return h*(7.5625*f*f)+a}else{if(f<(2/2.75)){return h*(7.5625*(f-=(1.5/2.75))*f+0.75)+a}else{if(f<(2.5/2.75)){return h*(7.5625*(f-=(2.25/2.75))*f+0.9375)+a}else{return h*(7.5625*(f-=(2.625/2.75))*f+0.984375)+a}}}},easeInOutBounce:function(e,f,a,h,g){if(f<g/2){return jQuery.easing.easeInBounce(e,f*2,0,h,g)*0.5+a}return jQuery.easing.easeOutBounce(e,f*2-g,0,h,g)*0.5+h*0.5+a}});

/**
 * jQuery resize event - v1.1 - 3/14/2010
 * http://benalman.com/projects/jquery-resize-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);

/**
 * jQuery throttle / debounce - v1.1 - 3/7/2010
 * http://benalman.com/projects/jquery-throttle-debounce-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);

/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 5/25/2009
 * @author Ariel Flesler
 * @version 1.4.2
 *
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 */
;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
