@@ -, +, @@ from the OPAC (1/2) targets screen. Note that not all targets support keyword search, but here are some that do: * Library of Congress: lx2.loc.gov, 210, LCDB, none, none, MARC21, UTF-8 * BNF2: z3950.bnf.fr, 2211, TOUT, Z3950, Z3950_BNF, UNIMARC, UTF-8 notice pops up at the top. should be clickable to bring up a detailed view of the record. --- C4/Search.pm | 30 + C4/XSLT.pm | 24 +- Makefile.PL | 2 +- admin/external_targets.pl | 125 +++ etc/koha-conf.xml | 13 - etc/koha-httpd.conf | 11 + etc/pazpar2/generic-settings.xml | 21 + etc/pazpar2/pazpar2.xml | 2 +- etc/pazpar2/unimarc-work-groups.xsl | 98 ++ .../intranet-tmpl/prog/en/css/staff-global.css | 26 +- .../intranet-tmpl/prog/en/includes/admin-menu.inc | 1 + .../prog/en/modules/admin/admin-home.tt | 2 + .../prog/en/modules/admin/external-targets.tt | 180 ++++ koha-tmpl/opac-tmpl/ccsr/en/css/opac.css | 16 + koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js | 106 ++ .../en/lib/jquery/plugins/jquery.lightbox_me.js | 254 +++++ koha-tmpl/opac-tmpl/lib/pz2.js | 1110 ++++++++++++++++++++ koha-tmpl/opac-tmpl/prog/en/css/opac.css | 18 +- koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js | 106 ++ .../en/lib/jquery/plugins/jquery.lightbox_me.js | 254 +++++ .../prog/en/modules/opac-external-search.tt | 240 +++++ .../opac-tmpl/prog/en/modules/opac-results.tt | 59 +- .../prog/en/xslt/MARC21slim2OPACResults.xsl | 6 +- .../opac-tmpl/prog/en/xslt/MARC21slimUtils.xsl | 2 +- .../prog/en/xslt/UNIMARCslim2OPACResults.xsl | 3 + opac/opac-external-search.pl | 65 ++ opac/opac-search.pl | 11 +- opac/svc/pazpar2_init | 99 ++ rewrite-config.PL | 8 +- 29 files changed, 2838 insertions(+), 54 deletions(-) create mode 100755 admin/external_targets.pl create mode 100644 etc/pazpar2/generic-settings.xml create mode 100644 etc/pazpar2/unimarc-work-groups.xsl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt create mode 100644 koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js create mode 100644 koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js create mode 100644 koha-tmpl/opac-tmpl/lib/pz2.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.lightbox_me.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-external-search.tt create mode 100755 opac/opac-external-search.pl create mode 100755 opac/svc/pazpar2_init --- a/C4/Search.pm +++ a/C4/Search.pm @@ -72,6 +72,7 @@ This module provides searching functions for Koha's bibliographic databases &GetDistinctValues &enabled_staff_search_views &SimpleSearch + &GetExternalSearchTargets ); # make all your functions, whether exported or not; @@ -2358,6 +2359,35 @@ sub _ZOOM_event_loop { } } +=head2 GetExternalSearchTargets + +Returns the list of Z39.50 servers that are marked for search in the OPAC using +Pazpar2. + +=cut + +sub GetExternalSearchTargets { + my ( $branchcode ) = @_; + + if ( $branchcode ) { + return C4::Context->dbh->selectall_arrayref( q{ + SELECT * FROM external_targets et + LEFT JOIN external_target_restrictions etr + ON (etr.target_id = et.target_id and etr.branchcode = ?) + WHERE etr.target_id IS NULL + ORDER BY et.name + }, { Slice => {} }, $branchcode ); + } else { + return C4::Context->dbh->selectall_arrayref( q{ + SELECT * FROM external_targets et + LEFT JOIN external_target_restrictions etr USING (target_id) + GROUP by et.target_id + HAVING branchcode IS NULL + ORDER BY et.name + }, { Slice => {} } ); + } +} + END { } # module clean-up code here (global destructor) --- a/C4/XSLT.pm +++ a/C4/XSLT.pm @@ -42,6 +42,7 @@ BEGIN { $VERSION = 3.07.00.049; @ISA = qw(Exporter); @EXPORT = qw( + &XSLTGetFilename &XSLTParse4Display &GetURI ); @@ -156,9 +157,10 @@ sub _get_best_default_xslt_filename { return $xslfilename; } -sub XSLTParse4Display { - my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; - my $xslfilename = C4::Context->preference($xslsyspref); +sub XSLTGetFilename { + my ( $marcflavour, $xslsyspref ) = @_; + + my $xslfilename = $marcflavour eq C4::Context->preference('marcflavour') ? C4::Context->preference($xslsyspref) : 'default'; if ( $xslfilename =~ /^\s*"?default"?\s*$/i ) { my $htdocs; my $theme; @@ -167,22 +169,22 @@ sub XSLTParse4Display { if ($xslsyspref eq "XSLTDetailsDisplay") { $htdocs = C4::Context->config('intrahtdocs'); $theme = C4::Context->preference("template"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2intranetDetail.xsl"; } elsif ($xslsyspref eq "XSLTResultsDisplay") { $htdocs = C4::Context->config('intrahtdocs'); $theme = C4::Context->preference("template"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2intranetResults.xsl"; } elsif ($xslsyspref eq "OPACXSLTDetailsDisplay") { $htdocs = C4::Context->config('opachtdocs'); $theme = C4::Context->preference("opacthemes"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2OPACDetail.xsl"; } elsif ($xslsyspref eq "OPACXSLTResultsDisplay") { $htdocs = C4::Context->config('opachtdocs'); $theme = C4::Context->preference("opacthemes"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2OPACResults.xsl"; } $xslfilename = _get_best_default_xslt_filename($htdocs, $theme, $lang, $xslfile); @@ -193,6 +195,14 @@ sub XSLTParse4Display { $xslfilename =~ s/\{langcode\}/$lang/; } + return $xslfilename; +} + +sub XSLTParse4Display { + my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; + + my $xslfilename = XSLTGetFilename( C4::Context->preference( 'marcflavour' ), $xslsyspref ); + # grab the XML, run it through our stylesheet, push it out to the browser my $record = transformMARCXML4XSLT($biblionumber, $orig_record); #return $record->as_formatted(); --- a/Makefile.PL +++ a/Makefile.PL @@ -534,7 +534,7 @@ if ($config{'INSTALL_ZEBRA'} eq "yes") { ); if ($config{'INSTALL_PAZPAR2'} eq 'yes') { push @{ $pl_files->{'rewrite-config.PL'} }, ( - 'blib/PAZPAR2_CONF_DIR/koha-biblios.xml', + 'blib/PAZPAR2_CONF_DIR/generic-settings.xml', 'blib/PAZPAR2_CONF_DIR/pazpar2.xml' ); } --- a/admin/external_targets.pl +++ a/admin/external_targets.pl @@ -0,0 +1,125 @@ +#!/usr/bin/perl +# +# Copyright 2013 Jesse Weaver +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +use Modern::Perl '2010'; + +use CGI; + +use C4::Auth; +use C4::Context; +use C4::Branch; +use C4::Output; +use URI::Escape; + +our $dbh = C4::Context->dbh; +our $input = new CGI; + +our ( $template, $loggedinuser, $cookie ) = get_template_and_user( { + template_name => "admin/external-targets.tt", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {parameters => 'parameters_remaining_permissions'}, + debug => 1, +} ); + +our $op = $input->param( 'op' ) // 'show'; +$template->{VARS}->{op} = $op; + +given ( $op ) { + when ( 'show' ) { show_external_targets(); } + when ( 'add' ) { show_edit_form(); } + when ( 'edit' ) { show_edit_form(); } + when ( 'save' ) { save_target(); } + when ( 'delete' ) { delete_target(); } +} + +output_html_with_http_headers $input, $cookie, $template->output; + +sub show_external_targets { + $template->{VARS}->{saved_id} = $input->param( 'saved_id' ); + $template->{VARS}->{deleted_name} = $input->param( 'deleted_name' ); + $template->{VARS}->{targets} = $dbh->selectall_arrayref( q{ + SELECT * + FROM external_targets + }, { Slice => {} } ); +} + +sub show_edit_form { + $template->{VARS}->{branches} = GetBranchesLoop( undef, 0 ); + $template->{VARS}->{syntaxes} = [ 'MARC21', 'UNIMARC', 'NORMARC' ]; + $template->{VARS}->{encodings} = { 'utf8' => 'UTF-8', 'marc8' => 'MARC-8' }; + + my $target_id; + if ( $target_id = $input->param( 'target_id' ) ) { + $template->{VARS}->{target} = $dbh->selectrow_hashref( q{ SELECT * FROM external_targets WHERE target_id = ? }, {}, $target_id ); + + my $available_branches = $dbh->selectall_hashref( q{ SELECT * FROM external_target_restrictions WHERE target_id = ? }, 'branchcode', {}, $target_id ); + + foreach my $branch ( @{ $template->{VARS}->{branches} } ) { + $branch->{selected} = 1 if ( $available_branches->{$branch->{branchcode}} ); + } + } +} + +sub save_target { + my $target_id; + if ( $target_id = $input->param( 'target_id' ) ) { + $dbh->do( q{ + UPDATE external_targets + SET name = ?, host = ?, port = ?, db = ?, userid = ?, password = ?, syntax = ?, encoding = ? + WHERE target_id = ? + }, {}, map { $input->param( $_ ) // '' } qw( name host port db userid password syntax encoding target_id ) ); + } else { + $dbh->do( q{ + INSERT + INTO external_targets(name, host, port, db, userid, password, syntax, encoding) + VALUES(?, ?, ?, ?, ?, ?, ?, ?) + }, {}, map { $input->param( $_ ) // '' } qw( name host port db userid password syntax encoding ) ); + $target_id = $dbh->last_insert_id( undef, undef, undef, undef ); + } + + $dbh->do( q{ + DELETE + FROM external_target_restrictions + WHERE target_id = ? + }, {}, $target_id ); + + foreach my $branchcode ( $input->param( 'branch' ) ) { + $dbh->do( q{ + INSERT + INTO external_target_restrictions(branchcode, target_id) + VALUES(?, ?) + }, {}, $branchcode, $target_id ); + } + + print $input->redirect( '/cgi-bin/koha/admin/external_targets.pl?saved_id=' . $target_id ); + exit; +} + +sub delete_target { + my ($target_id, $target); + + return unless ( $target_id = $input->param( 'target_id' ) and $target = $dbh->selectrow_hashref( q{ SELECT * FROM external_targets WHERE target_id = ? }, {}, $target_id ) ); + + $dbh->do( q{ DELETE FROM external_targets WHERE target_id = ? }, {}, $target_id ); + + print $input->redirect( '/cgi-bin/koha/admin/external_targets.pl?deleted_name=' . uri_escape( $target->{'name'} ) ); +} --- a/etc/koha-conf.xml +++ a/etc/koha-conf.xml @@ -19,19 +19,6 @@ tcp:@:__ZEBRA_SRU_BIBLIOS_PORT__ --> - -__PAZPAR2_TOGGLE_XML_PRE__ -tcp:@:__MERGE_SERVER_PORT__ - - __ZEBRA_DATA_DIR__/biblios - __ZEBRA_CONF_DIR__/__ZEBRA_BIB_CFG__ - __ZEBRA_CONF_DIR__/pqf.properties - -__PAZPAR2_TOGGLE_XML_POST__ - __ZEBRA_DATA_DIR__/biblios --- a/etc/koha-httpd.conf +++ a/etc/koha-httpd.conf @@ -106,6 +106,17 @@ RewriteRule ^/isbn/([^\/]*)/?$ /search?q=isbn:$1 [PT] RewriteRule ^/issn/([^\/]*)/?$ /search?q=issn:$1 [PT] + + __PAZPAR2_TOGGLE_HTTPD_PRE__ + + AddDefaultCharset off + Order deny,allow + Allow from all + + + ProxyRequests off + ProxyPass /pazpar2/search.pz2 http://__PAZPAR2_HOST__:__PAZPAR2_PORT__/search.pz2 + __PAZPAR2_TOGGLE_HTTPD_POST__ ## Intranet --- a/etc/pazpar2/generic-settings.xml +++ a/etc/pazpar2/generic-settings.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + --- a/etc/pazpar2/pazpar2.xml +++ a/etc/pazpar2/pazpar2.xml @@ -4,7 +4,7 @@ - + --- a/etc/pazpar2/unimarc-work-groups.xsl +++ a/etc/pazpar2/unimarc-work-groups.xsl @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + --- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css +++ a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css @@ -270,6 +270,16 @@ tr.even td, tr.even.highlight td { border-right : 1px solid #BCBCBC; } +tr.highlight td { + background-color : #F6F6F6; + border-color : #BCBCBC; +} + +tr.highlight th[scope=row] { + background-color : #DDDDDD; + border-color : #BCBCBC; +} + td.od { color : #cc0000; font-weight : bold; @@ -287,6 +297,10 @@ tr.odd.onissue td { background-color: #FFFFE1; } +tr.updated td { + background-color: #FFFFBB; +} + tfoot td { background-color : #f3f3f3; font-weight : bold; @@ -939,16 +953,6 @@ div.sysprefs div.hint { margin : .7em; } -tr.highlight td { - background-color : #F6F6F6; - border-color : #BCBCBC; -} - -tr.highlight th[scope=row] { - background-color : #DDDDDD; - border-color : #BCBCBC; -} - #circ_circulation_issue label { font-size: 105%; font-weight : bold; @@ -2570,4 +2574,4 @@ fieldset.rows table.mceListBox { font-size: 140%; font-family : monospace; padding : .3em; -} +} --- a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc @@ -46,6 +46,7 @@
  • Classification sources
  • Record matching rules
  • OAI sets configuration
  • +
  • External search targets
  • Acquisition parameters
    --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -84,6 +84,8 @@
    Search engine configuration
    Manage indexes, facets, and their mappings to MARC fields and subfields.
    [% END %] +
    External search targets
    +
    Define external search targets that can be searched from the OPAC.

    Acquisition parameters

    --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt @@ -0,0 +1,180 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% IF op == 'show' %] +Koha › Administration › External targets +[% ELSIF op == 'add' %] +Koha › Administration › External targets › Create an external target +[% ELSIF op == 'edit' %] +Koha › Administration › External targets › Editing '[% target.name %]' +[% END %] +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'datatables-strings.inc' %] + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + +[% IF op == 'show' %] + + + +[% ELSIF op == 'add' %] + + + +[% ELSIF op == 'edit' %] + + + +[% END %] + +
    +
    + +
    + +[% IF op == 'show' %] + +[% IF deleted_name %] +
    +

    Deleted target '[% deleted_name %]'

    +
    +[% END %] + + + +

    These Z39.50 targets are searched in the OPAC using the "external targets" feature. Note that Pazpar2 must be installed and configured for this to work.

    + +[% IF targets.size %] + + + + [% FOREACH target = targets %] + + + + + + + + + + [% END %] + +
    NameConnectionLoginSyntaxEncoding  
    [% target.name %][% target.host %]:[% target.port %]/[% target.db %][% IF target.userid %][% target.userid %] / [% IF target.password %]********[% ELSE %]none[% END %][% ELSE %]none[% END %][% target.syntax %] + [% IF target.encoding == 'marc8' %] + MARC-8 + [% ELSIF target.encoding == 'utf8' %] + UTF-8 + [% END %] + EditDelete
    +[% ELSE %] +

    No external targets have been defined yet.

    +[% END %] + +[% ELSIF op == 'add' || op == 'edit' %] + +
    + [% IF op == 'add' %] +

    Create an external target

    + [% ELSIF op == 'edit' %] +

    Editing '[% target.name %]'

    + [% END %] + + + + +
    +
      +
    1. +
    2. +
    3. +
    4. +
    5. +
    6. +
    7. + + +
    8. +
    9. + + +
    10. +
    11. + +
      + Not available to patrons from: +

      Only targets with no restrictions will be shown to anonymous (not logged in) users.

      +
        + [% FOREACH branch = branches %] +
      1. + + [% IF branch.selected %] + + [% ELSE %] + + [% END %] +
      2. + [% END %] +
      +
      +
    12. +
    +
    + +
    +
    + +[% END %] + +
    +
    +[% INCLUDE 'admin-menu.inc' %] +
    + +
    +[% INCLUDE 'intranet-bottom.inc' %] --- a/koha-tmpl/opac-tmpl/ccsr/en/css/opac.css +++ a/koha-tmpl/opac-tmpl/ccsr/en/css/opac.css @@ -1605,6 +1605,10 @@ strong em, em strong { vertical-align: top; width: 10px; } +.sourcecol { + vertical-align: top; + width: 100px; +} #container { color : #000; } @@ -2819,3 +2823,15 @@ a.reviewlink,a.reviewlink:visited { .subjectSearch ul { padding-left: 0px; } + +#modal-overlay { + background-color: white; + border-radius: 5px; + max-width: 75%; + padding: 15px; +} + +#overdrive-results, #pazpar2-results { + font-weight: bold; + padding-left: 1em; +} --- a/koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js +++ a/koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js @@ -0,0 +1,106 @@ +if ( typeof KOHA == "undefined" || !KOHA ) { + var KOHA = {}; +} + +KOHA.XSLTGet = ( function() { + // Horrible browser hack, but required due to the following hard-to-detect and long-unfixed bug: + // https://bugs.webkit.org/show_bug.cgi?id=60276 + var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); + var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor); + + if ( !isChrome && !isSafari ) return $.get; + + return function( url ) { + var result = new jQuery.Deferred(); + var basepath = url.match( /(.*\/)*/ )[0]; + + $.get( url ).done( function( xslDoc ) { + var xslImports = xslDoc.getElementsByTagNameNS( 'http://www.w3.org/1999/XSL/Transform', 'import' ); + var importsRemaining = xslImports.length; + + if ( importsRemaining == 0 ) { + result.resolve( xslDoc ); + return; + } + + $.each( xslImports, function( i, importElem ) { + var path = $( importElem ).attr( 'href' ); + if ( !/^(\/|https?:)/.test( path ) ) path = basepath + path; + + KOHA.XSLTGet( path ).done( function( subDoc ) { + importsRemaining--; + $( importElem ).replaceWith( subDoc.documentElement.childNodes ); + + if ( importsRemaining == 0 ) result.resolve( xslDoc ); + } ).fail( function() { + importsRemaining = -1; + + result.reject(); + } ); + } ); + } ).fail( function() { + result.reject(); + } ); + + return result; + }; +} )(); + +KOHA.TransformToFragment = function( xmlDoc, xslDoc ) { + if ( window.XSLTProcessor ) { + var proc = new XSLTProcessor(); + proc.importStylesheet( xslDoc ); + proc.setParameter( null, 'showAvailability', false ); + return (new XMLSerializer).serializeToString( proc.transformToFragment( xmlDoc, document ) ); + } else if ( window.ActiveXObject ) { + var xslt = new ActiveXObject( "Msxml2.XSLTemplate" ); + xslt.stylesheet = xslDoc; + var xslProc = xslt.createProcessor(); + xslProc.input = xmlDoc; + xslProc.addParameter( 'showAvailability', false ); + xslProc.transform(); + return xslProc.output; + } +}; + +KOHA.ExternalSearch = ( function() { + return { + targets: {}, + Search: function( q, limit, callback ) { + var targetIDs = []; + var includedTargets = []; + + $.each( KOHA.ExternalSearch.targets, function ( url, info ) { + if ( !info.disabled ) { + includedTargets.push( url ); + targetIDs.push( info.id ); + } + } ); + + if ( KOHA.ExternalSearch._pz !== undefined ) { + afterinit( KOHA.ExternalSearch._pz ); + } else { + $.get( '/cgi-bin/koha/svc/pazpar2_init', { targets: targetIDs.join(',') }, function( data ) { + KOHA.ExternalSearch._pz = new pz2({ + sessionId: data.sessionID, + onshow: callback, + errorhandler: function ( error ) { callback( { error: error } ) }, + } ); + afterinit( KOHA.ExternalSearch._pz ); + } ); + } + + function afterinit( pz ) { + pz.search( q, limit, 'relevance:0', 'pz:id=' + includedTargets.join( '|' ) ); + } + }, + Fetch: function( offset, callback ) { + var pz = KOHA.ExternalSearch._pz; + pz.showCallback = callback; + pz.show( offset ); + }, + GetDetailedRecord: function( recid, callback ) { + KOHA.ExternalSearch._pz.record( recid, 0, undefined, { callback: callback } ); + }, + }; +} )(); --- a/koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js +++ a/koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js @@ -0,0 +1,254 @@ +/* +* $ lightbox_me +* By: Buck Wilson +* Version : 2.3 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +(function($) { + + $.fn.lightbox_me = function(options) { + + return this.each(function() { + + var + opts = $.extend({}, $.fn.lightbox_me.defaults, options), + $overlay = $(), + $self = $(this), + $iframe = $('