1<!DOCTYPE html> 2<html lang="en-US"> 3<head>
4<script> 5window.PKD_GA_MODE='ga4'; 6window.PKD_GA_ECOMMERCE=true; 7window.pkdGaEvent=function(ev,params){try{if(!window.PKD_GA_ECOMMERCE)return;params=params||{};if(window.PKD_GA_MODE==='gtm'){window.dataLayer=window.dataLayer||[];dataLayer.push({ecommerce:null});dataLayer.push(Object.assign({event:ev},{ecommerce:params}));}else if(typeof gtag==='function'){gtag('event',ev,params);}}catch(e){}}; 8</script>
8 9 10<!-- Google Analytics 4 (gtag.js) -->
vendor: 64 bytes, lines 10-11
10 11<script async src="https://www.googletagmanager.com/gtag/js?id=
11G-SL79WKHR4T
vendor: 66 bytes, line 11
11" type="text/javascript" data-cookie-consent="tracking"></script>
12<script type="text/javascript" data-cookie-consent="tracking"> 13
vendor: 130 bytes, lines 13-16
13window.dataLayer = window.dataLayer || []; 14 function gtag(){dataLayer.push(arguments);} 15 gtag('js', new Date()); 16 gtag('config', '
16G-SL79WKHR4T
vendor: 36 bytes, lines 16-18
16', { 17 'cookie_domain': 'auto' 18 });
19</script>
19 20<meta charset="UTF-8" /> 21<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 22<title>The Kelmscott Bookshop | Contact Us</title> 23<meta name="description" content="Store hours and contact information for The Kelmscott Bookshop" /> 24<meta name="viewport" content="width=device-width, initial-scale=1.0" /> 25<meta property="og:site_name" content="The Kelmscott Bookshop" /> 26<meta property="og:url" content="https://www.kelmscottbookshop.com/contact.php" /> 27<meta name="author" content="www.bibliopolis.com" /> 28<meta name="robots" content="index, follow" /> 29<link href="https://www.kelmscottbookshop.com/contact.php" rel="canonical" /> 30<link href="https://kelmscottbookshop.cdn.bibliopolis.com/favicon.ico" rel="shortcut icon" /> 31
32<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"The Kelmscott Bookshop","@id":"https://www.kelmscottbookshop.com/","url":"https://www.kelmscottbookshop.com/","address":"Historic Savage Mill, #2021, Carding Building, Ste. G7, 8600 Foundry St., Savage, MD 20763","telephone":"(410) 235-6810","email":"[email protected]","logo":"https://www.kelmscottbookshop.com/images/logo.png"}</script>
vendor: 1 bytes, line 32
32
33<script type="text/javascript"> 34 var current_url = 'https%3A%2F%2Fwww.kelmscottbookshop.com%2Fcontact.php'; 35 var cim_refresh_url = '/manage-payment-profiles.php'; 36 var pkd_is_payment_page = false; 37 var use_3dsecure = false; 38 var disable_right_click = false;</script>
38 39 40
41<script crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/jquery/jquery-3.5.1.min.js?cors=1"></script>
vendor: 1 bytes, line 41
41
42<script crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/jquery/jquery-migrate-3.3.0.min.js?cors=1"></script>
42<script>var order_id = '0'; 43//all globals should go here 44var FS_APP_VERSION = "2.1"; 45var company_name = 'The Kelmscott Bookshop'; 46var old_type = ''; //used for old_type of cc in validation 47var modals = {}; //global of all modals used in a site 48 49var pkd_loc = { httppath: "https://www.kelmscottbookshop.com/", locale: "en_US", multilocale: 0, currency_loc: "en-US", currency: "USD" }; 50 51//paypal vars 52var paypal_currency = 'USD'; 53 54//cc globals 55var pay_type = '', is_valid = false, $cc_num = ''; 56 57//allowed data variables through ajax template 58var allowed_tpl_ajax_data = ['sku', 'order_item_id', 'tpl']; 59 60var pkd_gateway = "Square"; 61var currency = 'USD'; 62 63//cart errors/messages 64var general_cart_error = "Oops, something went wrong. Please try again."; 65var general_ajax_error = "Oops, there was an error with the page request."; 66var ajax_error = "Weâre having trouble connecting. Please try again."; 67var ajax_template_error = "There was a problem loading the content. Please try again."; 68var payment_form_error = "<strong>There was an issue loading the payment form</strong>%msg%Please <a href=\"javascript:window.location.reload();\" class=\"alert-link\">reload</a> the page."; 69var delete_confirm_msg = "Are you sure you want to remove this item?"; 70var general_liability_error = "We are unable to process your credit card. Please try again or enter a different payment method."; 71var credit_card_expired_error = "Credit card has expired."; 72var credit_card_select_error = "Please select a credit card."; 73var credit_card_required_error = "Please complete all credit card fields."; 74var gift_card_required_error = "Please select a gift card or enter a gift card number."; 75var missing_address_id_error = "Please select an existing address or add a new address."; 76var cart_cvv_amex_error = "Please enter a valid CVV. The CVV code is the four-digit code on the front of your card."; 77var cart_cvv_error = "Please enter a valid CVV. The CVV code is the three-digit code on the back of your card."; 78var cart_item_label = "%d"; 79var cart_item_label_plural = "%d"; 80var valid_amount_error = "Please enter a valid amount."; 81var valid_credit_card_error = "Please enter a valid credit card."; 82var paypal_signin_required_error = "You must sign into PayPal for payment."; 83var gw_default_edit_label = "Edit gift options"; 84var gw_default_label = "Make it a Gift"; 85var profile_delete_confirm = "Are you sure you want to delete this profile?"; 86var square_verify_error = "Please verify that your card information is correct. If you continue to have problems, please contact us."; 87var square_verify_gift_error = "Please verify that your gift card information is correct."; 88var cart_hide_label = "Hide Cart"; 89var cart_show_label = "Show Cart"; 90var purchase_order_num_error = "Please enter a purchase order number."; 91var paypal_general_error = "There was an error communicating with PayPal. Please try again, or contact us if you continue to have problems."; 92var expires_text = "Expires"; 93var cart_cc_ending_in_text = "ending in"; 94var po_number_text = "Purchase Order Number"; 95var payment_form_confirm = "You are about to submit a payment in the amount of %s. Are you sure?"; 96var saved_items_empty = "You have no saved items."; 97 98//general labels, errors, messages 99var required_fields_error = "Please fill in all required fields."; 100var wish_remove_confirm = "Are you sure you want to remove this item?"; 101var close_label = "Close"; 102var loading_label = "Loading..."; 103var previous_label = "Previous"; 104var next_label = "Next"; 105var primary_label = "Primary"; 106var secondary_label = "Secondary"; 107var sidebar_primary_label = "Primary Sidebar"; 108var sidebar_secondary_label = "Secondary Sidebar"; 109var sidebar_label = "Sidebar"; 110var slider_next_label = "Show Next Slide"; 111var slider_prev_label = "Show Previous Slide"; 112var gallery_view_image_alt = "Image %1$d of %2$d for %3$s"; 113var gallery_view_image_aria = "View Image %1$d of %2$d for %3$s"; 114var show_all_label = "Show All"; 115 116var wizard_finish_label = "Save and Close"; 117var google_recaptcha_response = "Google ReCaptcha Response"; 118 119//custom lightbox stuff 120//used with custom lightbox code 121var last_max_height = 0; //this is used for adding the inline max-height back onto image after it has been shrunk 122var enlarge_enabled = false; //will check on open if the enlarge/shrink toggle is enabled 123var boxed_enabled = false; //will check on open of the popup is boxed 124var custom_title_src = 'title'; //should be an attribute on the element selecting or a custom function 125//magnific popup language 126var magnific_popup_config = { 127 tClose: close_label, 128 tLoading: loading_label, 129 gallery: { 130 tPrev: previous_label, 131 tNext: next_label, 132 tCounter: "%curr% of %total%" 133 }, 134 image: { 135 tError: "<a href=\"%url%\">The image</a> could not be loaded." 136 }, 137 ajax: { 138 tError: "<a href=\"%url%\">The content</a> could not be loaded." 139 }} 140 141//bootbox 142bootbox_confirm_label = 'Confirm'; 143bootbox_cancel_label = 'Cancel'; 144 145function ajax_handler_app(params, args, data_dir, callback, debug = false) { 146 //console.log("ajax_handler_app called"); 147 if(typeof params !== 'undefined') { 148 args = (typeof args !== 'undefined' ? args : ''); 149 callback = callback || function (data, debug) { 150 var response = JSON.parse(data); 151 if(debug) console.log('Response:', response); 152 if (response.success) { 153 if(debug) console.log('Request successful:', response); 154 } else { 155 if(debug) console.log('Request failed:', response.msg); 156 } 157 }; 158 args = json_to_args(args); 159 // Send AJAX request 160 $.ajax({
161 type: "POST", 162 url: "/manager/include/ajax_call.php", // Actual path to your ajax_call.php 163 data: { 164 a_func: 'ajax_handler_app', // The PHP function to call 165 a_params: params + '|' + args, // Base64-encoded args, concatenated with the type 166 data_dir: data_dir // Pass the data_dir as a separate parameter 167 }, 168 success: callback, 169 error: function(xhr, status, error) { 170 console.error('Error occurred:', error); 171 } 172 }); 173 } 174} 175 176function json_to_args(json) { 177 let args = JSON.stringify(json); 178 179 //encode ~ specifically because they break JSON strings 180 //reserved for pointers in JSON 181 let args_encoded = args.replace('~', '~'); 182 183 //base64 encode 184 return encodeUnicode( args_encoded ); 185} 186 187function encodeUnicode(str) { 188 // first we use encodeURIComponent to get percent-encoded UTF-8, 189 // then we convert the percent encodings into raw bytes which 190 // can be fed into btoa. 191 return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, 192 function toSolidBytes(match, p1) { 193 return String.fromCharCode('0x' + p1); 194 })); 195} 196 197function query_string_to_json() { 198 var pairs = location.search.slice(1).split('&'); 199 200 var result = {}; 201 pairs.forEach(function(pair) { 202 pair = pair.split('='); 203 result[pair[0]] = decodeURIComponent(pair[1] || ''); 204 }); 205 206 return JSON.parse(JSON.stringify(result)); 207} 208 209function uniqid() { 210 function s4() { 211 return Math.floor((1 + Math.random()) * 0x10000) 212 .toString(16) 213 .substring(1); 214 } 215 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 216 s4() + '-' + s4() + s4() + s4(); 217} 218 219/** 220 * Replace Url Param or add it on if not there 221 * @param string url The url to replace the param in 222 * @param string paramName The name of the param to replace 223 * @param string paramValue The value to replace the param with 224 * @return string The new url 225 **/ 226function replaceUrlParam(url, paramName, paramValue) { 227 if (paramValue == null) { 228 paramValue = ''; 229 } 230 var pattern = new RegExp('\\b('+paramName+'=).*?(&|#|$)'); 231 if (url.search(pattern)>=0) { 232 return url.replace(pattern,'$1' + paramValue + '$2'); 233 } 234 url = url.replace(/[?#]$/,''); 235 return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue; 236} 237 238function append_tn_modal(callback) { 239 if($('#topic-notification-list-wrap').length == 0) { 240 $.ajax({ 241 url: "/modal-topic-notification.php", 242 success: function (data) { 243 $('#lyr-topic .modal-body').remove(); 244 $('#lyr-topic .modal-content').append(data); 245 246 if ( $.isFunction(callback) ) { 247 callback.call({ 248 data:data 249 }); 250 } 251 }, 252 dataType: 'html' 253 }); 254 } else { 255 if ( $.isFunction(callback) ) { 256 callback.call(); 257 } 258 } 259} 260function pkd_init_card_validator() { 261 if($('#fld_cardNumber').length > 0) { 262 $cc_num = $('#fld_cardNumber'); 263 var validateCCCallback = function (result) { 264 $(this).parent().removeClass('valid not-valid ' + old_type); 265 old_type = (result.card_type == null ? '' : result.card_type.name); 266 $('.card-number-validator').data('type', old_type); 267 is_valid = (result.valid && result.length_valid && result.luhn_valid); 268 $(this).parent().addClass((result.card_type == null ? '' : result.card_type.name) + (is_valid ? ' valid' : ' not-valid')); 269 if($("#cc_type").length > 0 && result.card_type != null) { 270 $("#cc_type").val(result.card_type.name); 271 } 272 }; 273 $('#fld_cardNumber').validateCreditCard(validateCCCallback); 274 } 275} 276 277//extended jquery functions always in use globally 278$.fn.extend({ 279 /********************************************************** 280 * Placeholder replacement for older browsers 281 * TODO: Remove this when we drop support for IE8 282 * @return void 283 **********************************************************/ 284 placeholder: function() { 285 $(this).find('input[type="text"], input[type="password"], textarea').each(function(ev){ 286 var placeholder = $(this).attr("placeholder"); 287 var is_textarea = $(this).is("textarea"); 288 if(typeof placeholder !== "undefined" && placeholder != "" && ($(this).val() == "") || (is_textarea && $(this).text() == "")) { 289 290 $t = $(this); 291 $t.addClass('hasPlaceholder'); 292 $t.attr("value", placeholder); 293 294 $t.bind("focus", function(){ 295 if( this.value == placeholder ) 296 this.value = ""; 297 }); 298 299 $t.bind("blur", function(){ 300 if( this.value == "" ) 301 this.value = placeholder; 302 }); 303 304 $(this).parents("form:first").submit(function(){ 305 306 var _t = $(this).find('.hasPlaceholder'); 307 if( _t.val() == placeholder ) 308 _t.val(""); 309 }); 310 } 311 }); 312 }, 313 /********************************************************** 314 * Clear form of all data 315 * TODO: Remove need for global.js clearForm() 316 * @return void 317 **********************************************************/ 318 clearForm: function(){ 319 this.each(function() { 320 $(this).click(function() { 321 322 var form = this; 323 while (form.nodeName != "FORM" && form.parentNode) { 324 form = form.parentNode; 325 } 326 327 clearForm(form); 328 with(form){ 329 if(typeof recordsLength !== 'undefined') 330 recordsLength.selectedIndex = 1; 331 332 if(typeof kwconj !== 'undefined') 333 kwconj[0].checked = true; 334 } 335 336 $(form).parent().find('.alert').remove(); 337 }); 338 }); 339 }, 340 /**********************************************************
341 * Allow alerts to show/hide depending on user cookie 342 * @param string key The key to use for the cookie 343 * @return void 344 **********************************************************/ 345 alert_cookie: function(key) { 346 this.each(function() { 347 //if key is not passed we'll just use default global message 348 key = key || 'global_message'; 349 350 //setup cookie if this is first time for user 351 if(typeof $.cookie(key) == "undefined") 352 $.cookie(key,'open',{path:'/'}); 353 354 //when we close the alert, set the cookie to closed for other interactions 355 $alert = $(this).find('.alert'); 356 if (key === 'global_message') { 357 $('body').on('closed.bs.alert', '#global-message', function() { 358 $.cookie(key, 'closed', { path: '/' }); 359 }); 360 } else { 361 $alert.bind('closed.bs.alert', function () { 362 $.cookie(key, 'closed', {path: '/'}); 363 }); 364 } 365 }); 366 }, 367 /********************************************************** 368 * Gets the natural width and height for an image 369 * @return object Has two keys width and height 370 **********************************************************/ 371 real_size: function() { 372 var $img = $(this); 373 if ($img.prop('naturalWidth') == undefined) { 374 var $tmpImg = $('<img/>').attr('src', $img.attr('src')); 375 $img.prop('naturalWidth', $tmpImg[0].width); 376 $img.prop('naturalHeight', $tmpImg[0].height); 377 } 378 return { width: $img.prop('naturalWidth'), height: $img.prop('naturalHeight') }; 379 }, 380 ajax_template: function(data, callback, callbackError) { 381 var $_this = $(this); 382 data = data || null; 383 callback = callback || null; 384 callbackError = callbackError || null; 385 if(data !== null) { 386 //only get parameters allowed by our application 387 var params = JSON.stringify(data, allowed_tpl_ajax_data); 388 //encode the parameters 389 var encoded_params = btoa(data.tpl+"|"+params); 390 data.tpl_action = data.tpl_action || 'html'; 391 $.ajax({ 392 type: "POST", 393 url: "/manager/include/ajax_call.php", 394 data: "a_func=pkd_get_template&a_params="+encoded_params, 395 success: function (response) { 396 switch(data.tpl_action) { 397 case 'append': 398 $_this.append(response); 399 break; 400 case 'prepend': 401 $_this.prepend(response); 402 break; 403 default: 404 $_this.html(response); 405 } 406 407 //setup callback for finished request 408 if ( $.isFunction(callback) ) { 409 callback.call({ 410 data:data, 411 target: $_this 412 }); 413 } 414 }, 415 error: function(jqXHR, textStatus, errorThrown) { 416 let statuscode = jqXHR.status || '000'; 417 418 if ( window.console && console.log ) 419 console.log('[ajax_template] [' + statuscode + '] '+(errorThrown != '' ? '['+errorThrown+'] ' : '') + ajax_template_error); 420 421 let data_tpl = (typeof data !== 'undefined' && 'tpl' in data ? data.tpl : 'no_tpl'); 422 let _params = btoa(JSON.stringify({action:'ajax_template_'+data_tpl})); 423 $.ajax({type: "POST", 424 url: "/manager/include/ajax_cart.php", 425 data: "a_func=update_connection_error&a_params="+_params}); 426 427 let error = `<div class="alert alert-danger">${ajax_template_error} <small>Error code:A${statuscode}</small></div>`; 428 if ( $.isFunction(callbackError) ) { 429 callbackError(error, $_this); 430 } else { 431 $_this.html(error); 432 } 433 } 434 }); 435 } else { 436 //setup callback for finished request 437 if ( $.isFunction(callback) ) { 438 callback.call(); 439 } 440 } 441 }, 442 //Counts down the number of remaining characters left 443 countCharValidation: function (num, selector) { 444 this.each(function () { 445 var 446 chars = "", 447 charCount = 0; 448 449 $(selector).text(num); 450 chars = $(this).val(); 451 var $remaining_chars = $(this).parent().find(selector); 452 $(this).keyup(function () { 453 chars = $(this).val(); 454 $.fn.countChar(chars, num, $remaining_chars); 455 }); 456 $.fn.countChar(chars, num, $remaining_chars); 457 }); 458 }, 459 countChar: function (str, num, selector) { 460 str = $.trim(str); 461 var charCount = (str == "" ? 0 : str.length); 462 var remaing = num - parseInt(charCount); 463 $(selector).text(remaing); 464 } 465 }); 466 467function escapeHtml(str){ 468 var entityMap = { 469 '&': '&', 470 '<': '<', 471 '>': '>', 472 '"': '"', 473 "'": ''', 474 '/': '/', 475 '`': '`', 476 '=': '=' 477 }; 478 return String(str).replace(/[&<>"'`=\/]/g, function (s) { 479 return entityMap[s]; 480 }); 481} 482 483/** 484 * Intl.NumberFormat as currencyFormatter 485 * Creates a proper price out of the entered amount. 486 * 487 */ 488const currencyFormatter = new Intl.NumberFormat(pkd_loc.currency_loc, { 489 style: 'currency', 490 currency: pkd_loc.currency, 491 minimumFractionDigits: 2 492}); 493 494/** 495 * Number.prototype.truncateToDecimals(dec) 496 * Truncates a number to only two decimal places without rounding 497 * Should do validation before using this function 498 * 499 * @param integer dec: length of decimal 500 * 501 */ 502Number.prototype.truncateToDecimals = function(dec) { 503 var dec = dec || 2; 504 var regex = /\./g; 505 var num_str = this.toString(); 506 507 if(num_str.match(regex)) { 508 // we have a number with a decimal 509 const calcDec = Math.pow(10, dec); 510 return Math.trunc(this * calcDec) / calcDec; 511 } else { 512 return this.toFixed(dec); 513 } 514}; 515 516const populate_wishlist_items = function(records){ 517 //console.log(typeof ajax_handler_app); // Should log 'function' 518 console.log('Records to filter for wishlist:', records); // Logs the returned SKUs 519 ajax_handler_app( 520 'wishlist|filter_records', // Params: Corresponds to the PHP file and action 521 { records: records }, // Arguments: Pass the records array 522 'search', // Data directory: Specify 'search' or any other directory 523 function(data, debug) { // Callback to handle success 524 let response = $.parseJSON(data); 525 if(debug) console.log('Response:', response); // Logs the returned SKUs 526 if (response.success) { 527 //if(debug) 528 console.log('Filtered records:', response.records); // Logs the returned SKUs 529 response.records.forEach(function(id) { 530 let wishlisthtml = '<span class="fa" aria-hidden="true"></span>Added to Wish List'; 531 if($('.wish-link[data-sku="' + id + '"] .wishlink-active-html').length > 0) { 532 wishlisthtml = $('.wish-link[data-sku="' + id + '"] .wishlink-active-html').html(); 533 } 534 let resethtml = '<span class="fa" aria-hidden="true"></span>Add to Wish List'; 535 $('.wish-link[data-sku="' + id + '"]').attr('href', '/cart.php').attr('aria-label', 'Added to Wish List').data('reset-html', resethtml).removeClass('wish-link-add').addClass('wish-link-added').html(wishlisthtml); 536 }); 537 } else { 538 console.log('Error:', response.msg); 539 } 540 } 541 ); 542} 543 544$(function(){ 545 //bootstrap 546 $.fn.button.Constructor.DEFAULTS = { 547 loadingText: 'Loading...' 548 } 549
550 //disable right click on anything marked with nocontextmenu 551 let nocontexters = document.getElementsByClassName('nocontextmenu'); 552 if(nocontexters.length > 0) { 553 for (let i = 0; i < nocontexters.length; i++) { 554 nocontexters[i].oncontextmenu = function(event) { 555 event.preventDefault(); // Prevent default context menu 556 }; 557 } 558 } 559 560 //disable right click on all parents of anything marked with nocontextmenu-parent 561 let parentnocontexters = document.getElementsByClassName('nocontextmenu-parent'); 562 if(parentnocontexters.length > 0) { 563 for (let i = 0; i < parentnocontexters.length; i++) { 564 let ele = parentnocontexters[i].parentNode; //get the parent node 565 ele.oncontextmenu = function(event) { 566 event.preventDefault(); // Prevent default context menu 567 }; 568 } 569 } 570 571 if (!("placeholder" in document.createElement("input"))) 572 $("form").placeholder(); 573 574 if($('#pkd_locale').length > 0) { 575 $('#pkd_locale').selectpicker({style: 'btn-link'}); 576 $('#pkd_locale').on('change', function (e) { 577 var url = $(this).find("option:selected").data('target') || ''; 578 if(url != '') { 579 try { 580 window.location.replace(url); 581 } catch (e) { 582 window.location = url; 583 } 584 } 585 }); 586 } 587 588 //setup lightbox in gallery mode 589 magnific_popup_config.type = 'image'; 590 magnific_popup_config.zoom = { 591 enabled: true, 592 opener: function(openerElement) { 593 //if the opener element is an image than use that to zoom 594 //else if there is no image inside the openerElement than find the image up a couple parents(used for detail page) 595 return (openerElement.is('img') ? openerElement : (openerElement.find('img').length > 0 ? openerElement.find('img') : openerElement.parent().parent().find('img'))); 596 } 597 }; 598 magnific_popup_config.gallery = { 599 enabled:true 600 }; 601 magnific_popup_config.image.markup = '<div class="mfp-figure">'+ 602 '<div class="mfp-close"></div>'+ 603 '<div class="mfp-enlarge"><a href="javascript:;" class="mfp-enlarge-link"></a></div>'+ 604 '<div class="mfp-img"></div>'+ 605 '<div class="mfp-bottom-bar">'+ 606 '<div class="mfp-title"></div>'+ 607 '<div class="mfp-counter"></div>'+ 608 '</div>'+ 609 '</div>'; 610 magnific_popup_config.image.titleSrc = custom_title_src; 611 magnific_popup_config.callbacks = { 612 open: function() { 613 $self = this; 614 if($self.wrap.find('.mfp-figure').css('position') != 'static') { 615 boxed_enabled = true; 616 } 617 618 $self.wrap.on('click', '.mfp-enlarge-link', function() { 619 620 let $img_ele = $(this).parent().parent().find('.mfp-img'); 621 $self.wrap.toggleClass('mfp-enlarged'); 622 if($self.wrap.hasClass('mfp-enlarged')) { 623 last_max_height = $img_ele.css('max-height'); 624 $img_ele.css('max-height', 'none'); 625 } else { 626 $img_ele.css('max-height', last_max_height); 627 } 628 }); 629 630 }, 631 beforeClose: function() { 632 if(enlarge_enabled) { 633 this.wrap.off('click', '.mfp-enlarge-link'); 634 this.wrap.removeClass('mfp-enlarged'); 635 } 636 }, 637 change: function() { 638 if(boxed_enabled) { 639 $.magnificPopup.instance.resizeImage.call(this); 640 } 641 }, 642 imageLoadComplete: function() { 643 $self = this; 644 if(boxed_enabled) { 645 $.magnificPopup.instance.resizeImage.call(this); 646 } 647 if($self.wrap.find('.mfp-enlarge').is(':visible')) { 648 enlarge_enabled = true; 649 } 650 651 let img_id = 'mfp-img-'+uniqid(); 652 let $img_ele = $self.wrap.find('.mfp-img'); 653 $img_ele.attr('id', img_id); 654 655 656 $self.wrap.removeClass('mfp-enlarged'); 657 var img_size = $img_ele.real_size(); 658 if(img_size.width <= $img_ele.width() ) { 659 $self.wrap.find(".mfp-enlarge").hide(); 660 } else { 661 $self.wrap.find(".mfp-enlarge").show(); 662 } 663 664 if(disable_right_click) { 665 let theimg = document.getElementById(img_id); 666 theimg.oncontextmenu = function (event) { 667 event.preventDefault(); // Prevent default context menu 668 }; 669 } 670 } 671 }; 672 $('.lightbox').magnificPopup(magnific_popup_config); 673 $.magnificPopup.instance.resizeImage = function() { 674 var mfp = $.magnificPopup.instance; 675 var item = mfp.currItem; 676 if(!item || !item.img) return; 677 678 if(mfp.st.image.verticalFit) { 679 var decr = 0; 680 // fix box-sizing in ie7/8 681 if(mfp.isLowIE) { 682 decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10); 683 } 684 var maxHeight = (mfp.wH-decr); 685 if(boxed_enabled) { 686 var bottomBarHeight = ( $('.mfp-title').outerHeight(true) + ($('.mfp-bottom-bar').outerHeight(true) - $('.mfp-bottom-bar').height() ) ); 687 var mfpFigure = $('.mfp-figure'); 688 maxHeight = maxHeight - ( ( (mfpFigure.outerHeight(true) - mfpFigure.height() ) + bottomBarHeight ) ); 689 } 690 item.img.css('max-height', maxHeight); 691 692 } 693 694 }; 695 696 //setup sharing tooltips 697 $('.share-icon').tooltip(); 698 $('.st_sharethis span').tooltip(); 699 700 //toggle login layer 701 $(".topic-notification-login").on('click', function(){ 702 $_tn_login_ele = $('.topic-notification-list-login-hide'); 703 $_tn_login_ele.parent().toggleClass('open'); 704 $_tn_login_ele.slideToggle(); 705 }); 706 707 //setup popovers for shipping links on order detail 708 if($(".ship-link-popover").length > 0 ) { 709 $(".ship-link-popover").each(function(){ 710 var popover_html = $(this).next().html(); 711 var options = { 712 html:true, 713 content:popover_html, 714 placement:'auto' 715 }; 716 $(this).popover(options); 717 }); 718 } 719 720 $('a[rel="external"]').on('click', function(e) { 721 e.preventDefault(); 722 window.open( $(this).attr('href') ); 723 }); 724 725 if( $(".clearForm").length > 0 ) {
726 $(".clearForm").clearForm(); 727 } 728 729 // see if referrer is a page within site 730 if($("#backHistory").length > 0) { 731 if(document.referrer.indexOf(window.location.hostname) != -1) 732 $('#backHistory').show(); 733 else 734 $('#backHistory').hide(); 735 } 736 737 //setup global namespace for modals 738 if($('#coupon_rules_modal').length > 0) modals.coupon = $('#coupon_rules_modal'); 739 if($('#cvv_modal').length > 0) modals.cvv = $('#cvv_modal'); 740 if($('#print_modal').length > 0) modals.print = $('#print_modal'); 741 if($('#order_history_modal').length > 0) { 742 modals.orderhistory = $('#order_history_modal'); 743 modals.orderhistory.on('hide.bs.modal', function () { 744 $(this).removeData('bs.modal'); 745 }); 746 } 747 748 if($('#lang_modal').length > 0) { 749 modals.lang = $('#lang_modal'); 750 modals.lang.on('hide.bs.modal', function () { 751 $('#modal-response-lang').html(''); 752 }); 753 $('#pkd_locale_preferred').selectpicker(); 754 $('.pkd-locale-preferred-dropdown .btn').append('<span class="fa fa-spinner fa-spin" />'); 755 $("#pkd_locale_preferred").on('change', function(e){ 756 var val = $(this).val(); 757 //only get parameters allowed by our application 758 if(val != '') { 759 var $icon = $(".pkd-locale-preferred-dropdown").find('.fa'); 760 var $response = $('#modal-response-lang'); 761 $icon.css('display', 'inline-block'); 762 $(this).prop('disabled', true); 763 $.ajax({
764 type: "POST", 765 url: "/manager/include/ajax_call.php", 766 data: "a_func="+ajax_registered_calls.setpreferredlocale+"&a_params="+val+"|", 767 success: function (response) { 768 $response.html(response); 769 }, 770 error: function(jqXHR, textStatus, error) { 771 if ( window.console && console.log ) 772 console.log('[set_preferred_locale] [' + textStatus + '] '+(error != '' ? '['+error+'] ' : '') + general_ajax_error); 773 $response.html('<div class="alert alert-sm alert-danger">'+general_ajax_error+'</div>'); 774 }, 775 complete: function(){ 776 $("#pkd_locale_preferred").prop('disabled', false); 777 $icon.css('display', 'none'); 778 } 779 }); 780 } 781 }); 782 } 783 784 /* Setup Topic Notification */ 785 if($('#lyr-topic').length > 0) { 786 modals.topics = $('#lyr-topic'); 787 modals.topics.on('hide.bs.modal', function (e) { 788 window.location.hash = ""; 789 }); 790 } 791 792 $('.topic-notification-link').on('click', function(e){ 793 e.preventDefault(); 794 $opener = $(this); 795 if( $opener.hasClass("mobile") && $opener.data('mobile') != '' ) { 796 window.location = $opener.data('mobile'); 797 } else if( ! $.isEmptyObject(modals.topics) ) { 798 append_tn_modal(function(){ 799 modals.topics.modal('show'); 800 801 //set hash to topics 802 if(!window.location.hash) { 803 window.location.hash = "topics"; 804 } 805 806 if($(".widget_el_email_wrap_loggedin").length > 0) { 807 var url = $(".widget_el_email_wrap_loggedin a").attr("href"); 808 if(url.indexOf("topics") == "-1") 809 $(".widget_el_email_wrap_loggedin a").attr("href", url+"#topics"); 810 } 811 }); 812 } 813 }); 814 815 //if we have a hash tag 816 if(window.location.hash) 817 { 818 switch(window.location.hash) 819 { 820 //when hash is topics then open topic modal 821 case "#topics": 822 append_tn_modal(function(){ 823 if( ! $.isEmptyObject(modals.topics) ) 824 { 825 modals.topics.modal('show'); 826 } 827 }); 828 break; 829 } 830 } 831 $('.want-link-remove').on('click', function(e){ 832 e.preventDefault(); 833 if(confirm(wish_remove_confirm)){ 834 window.location=$(this).attr('href'); 835 } 836 }); 837 838 839 $(document).on('click', '.mock-anchor', function(e) { 840 var url = $(this).data('url') || ''; 841 var target = $(this).data('url-target') || ''; 842 if($.trim(url) != '') { 843 if($.trim(target) == '') { 844 window.location = url; 845 } else { 846 window.open(url,target); 847 } 848 } 849 }); 850 851 if($('.flex-form').length > 0) { 852 853 $(".flex-form-link").on('click', function(e){ 854 e.preventDefault(); 855 856 var target = $(this).attr('href'); 857 858 //show flex form layer 859 $(target).addClass('display-flex'); 860 861 //flex layer no longer hidden to user 862 $(target).attr('aria-hidden', 'false'); 863 864 //keyup event for closing the popup once opened 865 $(document).keyup(function(e) { 866 // esc to close flex form 867 if (e.keyCode === 27) $(target).trigger('click'); 868 }); 869 870 //wait a short very brief moment to show the form 871 setTimeout(function(){ 872 //make form active and visible 873 $(target).find('.flex-form-inner').addClass('active'); 874 875 //focus on first element 876 var $form = $(target).find('form'); 877 $form.find("input[type!='hidden'],select,textarea").first().focus(); 878 }, 50); 879 }); 880 881 $('.flex-form').on('click', function(e) { 882 //hide the form and form layer 883 $(this).removeClass('display-flex').attr('aria-hidden', 'true'); 884 $(this).find(".flex-form-inner").removeClass('active'); 885 886 //unbind esc keyup event 887 $(document).off('keyup'); 888 }); 889 890 $(".flex-form form").each(function(idx,obj){ 891 $(this).addClass('is-flex'); 892 $(this).on('click', function(e){ 893 //allow you to click inside the form without closing the layer 894 e.stopPropagation(); 895 }); 896 }); 897 } 898 899 /* Fix for Accessibilty */ 900 $('.btn-group-fix .btn').on('click', function(){ 901 $parent = $(this).parent(); 902 $parent.find('input').prop('checked', false); 903 $(this).next().prop('checked',true); 904 $(this).closest('form').submit(); 905 }); 906
907 /* Load cached content */ 908 // Define the mapping array 909 const cacheMap = [ 910 { cacheFile: '/cache.site_message.php', target: '#global-message', classToAdd: (typeof $.cookie('global_message') == "undefined" ? 'open' : $.cookie('global_message')) }, 911 { cacheFile: '/cache.vacation.php', target: '#vacation-message' }, 912 ]; 913 914 // Function to load content via AJAX 915 function loadCacheContent(cacheFile, target, classToAdd) { 916 $.ajax({ 917 url: cacheFile, // The cache file URL 918 method: 'GET', 919 success: function (response) { 920 //console.log('Raw response:', response); // Log the response to see exactly what we're getting 921 // Wrap the response in a jQuery object 922 const $responseHTML = $(response); 923 924 // Check if the response contains the target element directly 925 const $content = $responseHTML.is(target) ? $responseHTML : $responseHTML.find(target); 926 927 if ($content.length) { 928 // Inject content into the page 929 $(target).html($content.html()); 930 // Check if classToAdd is provided and add the class if needed 931 if (classToAdd) { 932 $(target).addClass(classToAdd); 933 } 934 // Remove the display:none inline style if it exists 935 $(target).css('display', ''); // Reset to default (removes inline display setting) 936 // a banner that may not be dismissed shows whatever an earlier dismissal cookie says (Sept 2026) 937 if ($(target).find('.ann-no-dismiss').length) { 938 $(target).removeClass('closed').addClass('open'); 939 } 940 } /* else { 941 console.error('Target not found in the response'); 942 } */ 943 }, 944 error: function () { 945 console.error('Failed to load content from ' + cacheFile); 946 } 947 }); 948 } 949 950 // Loop through the mapping array and load content if the target is found on the page
951 cacheMap.forEach(function (item) { 952 // a placeholder rendered INLINE under a content-preview token is the preview: never overwrite it 953 if ($(item.target).length && !$(item.target).is('[data-ann-preview]')) { // Check if the target exists on the page 954 loadCacheContent(item.cacheFile, item.target, item.classToAdd); 955 } 956 }); 957 958 /* Global content slots â fill every [data-global-content] placeholder from the 959 externalized manifest (cache.global_content[.locale].json). Keeps editable global 960 blocks (footer, announcement bar, â¦) out of the cached page HTML so an edit needs 961 no page purge. See pkd_publish_global_content() / pkd_global_content() in PHP. */ 962 loadGlobalContent(); 963 function loadGlobalContent() { 964 var $slots = $('[data-global-content]'); 965 if (!$slots.length) return; 966 var loc = (typeof pkd_loc === 'object' && pkd_loc && pkd_loc.multilocale && pkd_loc.locale) ? pkd_loc.locale : ''; 967 var url = '/cache.global_content' + (loc ? '.' + loc : '') + '.json'; 968 function fill(map) { 969 if (!map || typeof map !== 'object') return; 970 $slots.each(function () { 971 var name = $(this).attr('data-global-content'); 972 if (map.hasOwnProperty(name)) $(this).html(map[name]); 973 }); 974 } 975 /* No-cache REQUEST header: the static .json otherwise gets heuristically 976 cached by the browser (Last-Modified present) and an edited slot looks 977 stale for hours â this forces revalidation (cheap 304s) while the URL 978 stays stable so the CDN still edge-caches it (purged on edit). */ 979 function fetchManifest(u) { 980 return $.ajax({ url: u, dataType: 'json', cache: true, headers: { 'Cache-Control': 'no-cache' } }); 981 } 982 fetchManifest(url).done(fill).fail(function () { 983 // locale-specific manifest missing â fall back to the base file
984 if (loc) fetchManifest('/cache.global_content.json').done(fill); 985 }); 986 } 987 988 989 $('.tpl-load').each(function(){ 990 var $this = $(this); 991 $this.ajax_template({ 992 'tpl': $this.data('tpl') 993 }, function(){ 994 cart = $("#utils-cart").pkdcart('update_values'); 995 if($('#pkd_locale').length > 0) { 996 $('#pkd_locale').selectpicker({style: 'btn-link'}); 997 $('#pkd_locale').on('change', function (e) { 998 var url = $(this).find("option:selected").data('target') || ''; 999 if(url != '') { 1000 try { 1001 window.location.replace(url); 1002 } catch (e) { 1003 window.location = url; 1004 } 1005 } 1006 }); 1007 } 1008 }); 1009 }); 1010 1011 // Display the cookie consent banner if enabled 1012 1013}); 1014 1015function modal_error_callback(error, target) { 1016 console.log(error); 1017 console.log(target); 1018 $(target).html(`<div class="modal-dialog"> 1019 <div class="modal-content"> 1020 <div class="modal-body"> 1021 <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button> 1022 1023 ${error} 1024 </div> 1025 </div> 1026</div>`); 1027 1028 target.modal('show'); 1029}</script>
vendor: 2 bytes, line 1029
1029
1030<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/sprintf.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1030
1030
1031<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/global.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1031
1031
1032<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/browser-detection.js?v=1775748982&cors=1"></script>
vendor: 1 bytes, line 1032
1032
1033<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/bootstrap.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1033
1033
1034<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/bootstrap-hover-dropdown.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1034
1034
1035<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/bootbox.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1035
1035
1036<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/pkd.accessibility.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1036
1036
1037<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.magnific.lightbox.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1037
1037
1038<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.touchSwipe.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1038
1038
1039<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.ba-throttle-debounce.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1039
1039
1040<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.mmenu.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1040
1040
1041<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.superfish.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1041
1041
1042<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.cookie.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1042
1042
1043<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery-ui-1.10.4-slider-only.custom.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1043
1043
1044<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.mmenu.header.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1044
1044
1045<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/cycle.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1045
1045
1046<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.creditCardValidator.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1046
1046
1047<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.easing.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1047
1047
1048<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.transit.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1048
1048
1049<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.create.plugin.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1049
1049
1050<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.pkd.cart.min.js?v=1775744060&cors=1"></script>
vendor: 1 bytes, line 1050
1050
1051<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.modmb.wizard.min.js?v=1758203350&cors=1"></script>
vendor: 1 bytes, line 1051
1051
1052<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/pkd.cart.min.js?v=1788283544&cors=1"></script>
vendor: 1 bytes, line 1052
1052
1053<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/pkd.cart.payment.min.js?v=1784649283&cors=1"></script>
vendor: 1 bytes, line 1053
1053
1054<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/jquery.jscroll.min.js?v=1697161894&cors=1"></script>
vendor: 1 bytes, line 1054
1054
1055<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/lib/pkd.cart.saved_items.min.js?v=1761328870&cors=1"></script>
vendor: 1 bytes, line 1055
1055
1056<script type="text/javascript" src="/manager/include/scripts/scripts.js?v=1752693000"></script>
1056 1057 1058<link rel="stylesheet" href="/css/custom-bootstrap.css?v=2.1.1787328454" type="text/css" /> 1059 1060 1061
1062<script type="text/javascript" src="https://www.bibliopolis.com/manager/include/scripts/session.js?v=1774540996&cors=1" data-cookie-consent="functionality"></script>
1062 1063 1064
1065<script src="/manager/include/scripts/load.js?v=1775491360"></script>
1065 1066 1067 1068 1069</head> 1070 1071 1072<!--[if lte IE 7]> <body class="contact en-us isDesktop ie ie7 ieOld"> <![endif]--> 1073<!--[if IE 8]> <body class="contact en-us isDesktop ie ie8"> <![endif]--> 1074<!--[if gte IE 9]> <body class="contact en-us isDesktop ie ie9"> <![endif]--> 1075<!--[if gt IE 9]><!--> <body class="contact en-us isDesktop nonie"> <!--<![endif]--> 1076<!-- Cookie Consent by TermsFeed https://www.TermsFeed.com -->
1077<script type="text/javascript" crossorigin="anonymous" src="https://www.bibliopolis.com/manager/include/scripts/cookie-consent.js?cors=1" charset="UTF-8"></script>
1077 1078<!-- End Cookie Consent by TermsFeed https://www.TermsFeed.com --> 1079<div id="outer-page-wrapper"> 1080 <div id="global-message" class="div-p" style="display:none;"></div> <header id="header-wrapper"> 1081 <a class="sr-only" id="skip-navigation" href="#main-content">Skip to main content</a> 1082 <div id="masthead-container"> 1083 <div class="container"> 1084 <div class="row"> 1085 <div class="masthead col-sm-6"> 1086 <h1 class="hidden">The Kelmscott Bookshop</h1> 1087 <a href="https://www.kelmscottbookshop.com/" title="The Kelmscott Bookshop"> 1088 <img src="/images/logo.png" class="img-responsive" alt="The Kelmscott Bookshop" > 1089 </a> 1090 </div> 1091 <div id="top" class="col-sm-5 col-sm-offset-1 col-md-4 col-md-offset-2"> 1092 <div class="top-group" id="utils-nav"> 1093 <div class="dropdown util-link " id="utils-account"> 1094 <button class="dropdown-toggle btn-link" type="button" data-toggle="dropdown" data-hover="dropdown" data-delay="1000" data-close-others="false">Account <span class="fa fa-caret-down" aria-hidden="true"></span></button> 1095 <ul class="dropdown-menu dropdown-menu-center"> 1096 <li><a class="btn btn-primary btn-sm btn-account" href="https://www.kelmscottbookshop.com/login.php">Sign in</a></li> 1097 <li role="separator" class="divider"></li> 1098 <li><a href="https://www.kelmscottbookshop.com/myaccount.php">Your Account</a></li> 1099 <li><a href="https://www.kelmscottbookshop.com/order-history.php">Order History</a></li> 1100 <li><a href="https://www.kelmscottbookshop.com/WantList.php">Want List</a></li> 1101 <li><a href="https://www.kelmscottbookshop.com/wish-list.php">Wish List</a></li> 1102 <li><a href="https://squareup.com/gift/ARZHHT9NDXHFZ" target="_blank">Gift Cards</a></li> 1103 </ul> 1104</div> 1105<div class="util-link" id="utils-cart"><a href="https://www.kelmscottbookshop.com/cart.php"><span class="fa fa-shopping-cart" aria-hidden="true"></span><span class="cartNumItems"></span><span class="sr-only"> items in Cart</span></a></div> 1106 </div> 1107 <div class="top-group hidden-xs" id="quick-search-wrapper"> 1108 <form name="quick_search_1" id="quick_search_1" action="/advSearchResults.php" method="get" class=" has-labels " role="search"> 1109 <input type="hidden" name="action" value="search" /> 1110 <input type="hidden" name="orderBy" value="relevance" /> 1111 <input type="hidden" name="category_id" value="0" /> 1112 <div class="input-group "> 1113 <span class="input-group-addon"><label for="quick_search_1-keywords" aria-hidden="true" class="control-label">Search</label></span> 1114 <input class="form-control" id="quick_search_1-keywords" aria-label="Search" type="text" placeholder="author, title, or keyword" name="keywordsField"> 1115 <span class="input-group-btn"><button class="btn btn-primary" type="submit"><span class="fa fa-search" aria-hidden="true"></span><span class="sr-only">Submit Search</span></button></span> 1116 </div> 1117 <div class="help-block text-right"><a href="https://www.kelmscottbookshop.com/advSearch.php">Advanced Search</a></div> 1118 </form> </div> 1119 </div> 1120 </div> 1121 </div> 1122 </div> 1123 <div id="navbar-container"> 1124 <div class="container"> 1125 <nav id="nav" role="navigation" class="navbar navbar-default navbar-inner"> 1126 <h1 class="hidden">Main Navigation</h1> 1127 <div class="navbar-header"> 1128 <form name="quick_search_nav" id="quick_search_nav" action="/advSearchResults.php" method="get" class="visible-xs group has-labels " role="search"> 1129 <input type="hidden" name="action" value="search" /> 1130 <input type="hidden" name="orderBy" value="relevance" /> 1131 <input type="hidden" name="category_id" value="0" /> 1132 <a href="#navbar" class="btn btn-navbar navbar-toggle"><span class="sr-only">Toggle main navigation</span><span class="fa fa-bars"></span></a> 1133 <div class="input-group "> 1134 <input class="form-control" id="quick_search_nav-keywords" aria-label="Search" type="text" placeholder="author, title, or keyword" name="keywordsField"> 1135 <span class="input-group-btn"><button class="btn btn-primary" type="submit"><span class="fa fa-search" aria-hidden="true"></span><span class="sr-only">Submit Search</span></button></span> 1136 </div> 1137 </form> 1138 </div> 1139 <div id="nav-wrapper" class=""> 1140 <div class="navbar-static-top" role="navigation"> 1141 <div id="navbar" class="collapse navbar-collapse"> 1142 1143 <ul class="nav navbar-nav"> 1144 <li class="nav-parent nav-menu-search-inventory has-submenu"> 1145 <a href="https://www.kelmscottbookshop.com/advSearch.php" class="nav-parent-a" target="_self" >Search Inventory</a> 1146 1147 <ul class="list-unstyled"> 1148 <li class="nav-child nav-submenu-books "> 1149 <a href="https://www.kelmscottbookshop.com/advSearch.php?m=1" class="nav-child-a" target="_self" >Books</a> 1150 </li><li class="nav-child nav-submenu-catalogs "> 1151 <a href="https://www.kelmscottbookshop.com/catalogs.php" class="nav-child-a" target="_self" >Catalogs</a> 1152 </li><li class="nav-child nav-submenu-manuscripts-prints "> 1153 <a href="https://www.kelmscottbookshop.com/manuscripts-prints.php" class="nav-child-a" target="_self" >Manuscripts & Prints</a> 1154 </li><li class="nav-child nav-submenu-new-arrivals "> 1155 <a href="https://www.kelmscottbookshop.com/new-arrivals.php" class="nav-child-a" target="_self" >New Arrivals</a> 1156 </li><li class="nav-child nav-submenu-featured-books "> 1157 <a href="https://www.kelmscottbookshop.com/featured.php" class="nav-child-a" target="_self" >Featured Books</a> 1158 </li><li class="nav-child nav-submenu-sale-books "> 1159 <a href="https://www.kelmscottbookshop.com/sale-books.php" class="nav-child-a" target="_self" >Sale Books</a> 1160 </li><li class="nav-child nav-submenu-lots "> 1161 <a href="https://www.kelmscottbookshop.com/lots.php" class="nav-child-a" target="_self" >Lots</a> 1162 </li><li class="nav-child nav-submenu-advanced-search "> 1163 <a href="https://www.kelmscottbookshop.com/advSearch.php?m=2" class="nav-child-a" target="_self" >Advanced Search</a> 1164 </li><li class="nav-child nav-submenu-browse-categories "> 1165 <a href="https://www.kelmscottbookshop.com/browse.php" class="nav-child-a" target="_self" >Browse Categories</a> 1166 </li><li class="nav-child nav-submenu-wants "> 1167 <a href="https://www.kelmscottbookshop.com/WantList.php" class="nav-child-a" target="_self" >Wants</a> 1168 </li> 1169 </ul></li><li class="nav-parent nav-menu-about-the-bookshop has-submenu"> 1170 <a href="https://www.kelmscottbookshop.com/about.php?m=1" class="nav-parent-a" target="_self" >About the Bookshop</a> 1171 1172 <ul class="list-unstyled"> 1173 <li class="nav-child nav-submenu-about-us "> 1174 <a href="https://www.kelmscottbookshop.com/about.php" class="nav-child-a" target="_self" >About Us</a> 1175 </li><li class="nav-child nav-submenu-shop-history "> 1176 <a href="https://www.kelmscottbookshop.com/shophist.php" class="nav-child-a" target="_self" >Shop History</a> 1177 </li><li class="nav-child nav-submenu-directions-hours "> 1178 <a href="https://www.kelmscottbookshop.com/directions.php" class="nav-child-a" target="_self" >Directions/Hours</a> 1179 </li><li class="nav-child nav-submenu-events "> 1180 <a href="https://www.kelmscottbookshop.com/events.php" class="nav-child-a" target="_self" >Events</a> 1181 </li><li class="nav-child nav-submenu-contact-us CSS3support active"> 1182 <a href="https://www.kelmscottbookshop.com/contact.php" class="nav-child-a" target="_self" aria-current="page">Contact Us</a> 1183 </li><li class="nav-child nav-submenu-faqs "> 1184 <a href="https://www.kelmscottbookshop.com/faqs.php" class="nav-child-a" target="_self" >FAQs</a> 1185 </li><li class="nav-child nav-submenu-useful-links "> 1186 <a href="https://www.kelmscottbookshop.com/links.php" class="nav-child-a" target="_self" >Useful Links</a> 1187 </li> 1188 </ul></li><li class="nav-parent nav-menu-sell-to-us "> 1189 <a href="https://www.kelmscottbookshop.com/sell-to-us.php" class="nav-parent-a" target="_self" >Sell To Us</a> 1190 </li><li class="nav-parent nav-menu-manuscripts-prints "> 1191 <a href="https://www.kelmscottbookshop.com/manuscripts-prints.php" class="nav-parent-a" target="_self" >Manuscripts & Prints</a> 1192 </li><li class="nav-parent nav-menu-bab-home has-submenu"> 1193 <a href="https://www.kelmscottbookshop.com/book-arts-baltimore.php" class="nav-parent-a" target="_self" >BAB Home</a> 1194 1195 <ul class="list-unstyled"> 1196 <li class="nav-child nav-submenu-resources "> 1197 <a href="https://www.kelmscottbookshop.com/book-arts-baltimore-resources.php" class="nav-child-a" target="_self" >Resources</a> 1198 </li><li class="nav-child nav-submenu-scholarships-fellowships "> 1199 <a href="https://www.kelmscottbookshop.com/book-arts-baltimore-scholarships-and-fellowships.php" class="nav-child-a" target="_self" >Scholarships & Fellowships</a> 1200 </li> 1201 </ul></li><li class="nav-parent nav-menu-book-arts has-submenu"> 1202 <a href="https://www.kelmscottbookshop.com/searchResults.php?category_id=322&action=browse&orderBy=author" class="nav-parent-a" target="_self" >Book Arts</a> 1203 1204 <ul class="list-unstyled"> 1205 <li class="nav-child nav-submenu-artists-books "> 1206 <a href="https://www.kelmscottbookshop.com/artists-books.php" class="nav-child-a" target="_self" >Artist's Books</a> 1207 </li><li class="nav-child nav-submenu-private-press "> 1208 <a href="https://www.kelmscottbookshop.com/private-press.php" class="nav-child-a" target="_self" >Private Press</a> 1209 </li><li class="nav-child nav-submenu-book-arts-baltimore ">
1210 <a href="https://www.kelmscottbookshop.com/book-arts-baltimore.php" class="nav-child-a" target="_self" >Book Arts Baltimore</a> 1211 </li><li class="nav-child nav-submenu-resources "> 1212 <a href="https://www.kelmscottbookshop.com/book-arts-baltimore-resources.php" class="nav-child-a" target="_self" >Resources</a> 1213 </li> 1214 </ul></li><li class="nav-parent nav-menu-contact CSS3support active"> 1215 <a href="https://www.kelmscottbookshop.com/contact.php" class="nav-parent-a" target="_self" aria-current="page">Contact</a> 1216 </li> 1217 </ul> </div> 1218 1219 </div> 1220 </div> 1221 </nav> 1222 </div> 1223 </div> 1224 </header> 1225 <div id="body-container"> <div class="container"> 1226 1227 1228 <main id="main-content" role="main" class=""><article class="html-block"> 1229 <h1>Contact Us</h1> <div id="contactFB"><a href="http://www.facebook.com/pages/Baltimore-MD/142614879117082" target="_blank"><img style="float: right;" src="/images/custom/fb.gif" alt="" /></a></div> <p data-renderer-start-pos="1114"><strong>Send letter mail only to:</strong><br />The Kelmscott Bookshop<br />Box 2021<br />8600 Foundry St.<br />Savage, MD 20763</p> <p data-renderer-start-pos="1114">(If visiting, we are in the Carding Building, Suite G-7)</p> <p data-renderer-start-pos="1210"><strong>Send packages to:</strong><br />Stephen Durako<br />9466 Georgia Avenue, #1172<br />Silver Spring, MD 20910</p> <p><span><a href="tel:+14102356810" class="link-tel">(410) 235-6810</a></span></p> <p><strong>Hours:</strong> By appointment only. We are often in the shop Monday, Wednesday, and Friday; however, we no longer keep regular hours.</p> <p>We continue to offer in-store pickup. This is at the Savage Mill address, Suite G-7.  </p> <p>e-mail <a href="mailto:[email protected]">[email protected]</a></p> <p> </p> <p><iframe style="border: 0;" width="100%" height="350" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3086.685180577481!2d-76.620300049
122912039!3d39.31805912954271!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x89c804e81d77b8e7%3A0x13af9239338c7c7d!2sKelmscott+Bookshop!5e0!3m2!1sen!2sau!4v1499404942994" frameborder="0"></iframe></p> <div class="group" style="margin: 40px 0 0 0px;"> <h2>Join Our Mailing List</h2> <p><a href="https://www.kelmscottbookshop.com/createAccount.php">Click here</a> to create an account on our website. This will automatically add you to our mailing list and means that from time-to-time you may receive updates on special offers and events. <a href="https://www.kelmscottbookshop.com/createAccount.php">Sign up now!</a></p> <h2>Online Inventory</h2> <p>Search our online inventory with our <a href="https://www.kelmscottbookshop.com/advSearch.php">Advanced Search</a></p> <h2>Website Wants</h2> <p>You can leave wants on our website, and we will notify you by e-mail when a match has been uploaded to our website. Be sure to <a href="https://www.kelmscottbookshop.com/createAccount.php">create an account</a> so that you can manage your wants at any time.</p> </div> </article> 1230 </main> 1231 1232 </div> 1233</div> 1234<div id="pre-footer-container"> 1235 <div class="container"> 1236 <div id="footer-signup"> 1237 <div class="row"> 1238 <div class="col-sm-5 col-md-4"><h2>Newsletter Signup</h2></div> 1239 <div class="col-sm-7 col-md-5"> 1240 1241<div id="footer-subscribe1"> 1242<div id="widget_cc_email_box_message1" class="remove"></div> 1243<form action="#" name="widget_cc_form1" method="post" class="" id="footer-subscribe" data-widget-id="constantcontact_signup"> <div class="input-group"> 1244 1245 <input type="text" value="" aria-label="Email" placeholder="Your Email" name="widget_cc_email" id="widget_cc_email" class="form-control required" /> 1246 <span class="input-group-btn"><button type="submit" class="btn btn-default" name="submit" data-loading-text="<i class='fa fa-spinner fa-spin'></i>">Sign Up</button></span> 1247 </div> 1248 1249 1250</form></div> 1251 </div> 1252 </div> 1253 </div> 1254</div> 1255<footer id="footer-container"> 1256 <div class="container"> 1257 <div class="footer"> 1258 <div class="row"> 1259 <div class="col-xs-6 col-sm-3 col-md-3"> 1260 <ul class="list-unstyled"> 1261 <li><strong>The Kelmscott Bookshop</strong></li> 1262 <li> 1263 Historic Savage Mill, #2021<br />Carding Building, Ste. G7<br />8600 Foundry St.<br />Savage, MD 20763 </li> 1264 <li>Phone <a href="tel:+14102356810" class="link-tel">(410) 235-6810</a></li> 1265 <li>
1265<script type="text/javascript">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%69%6e%66%6f%40%6b%65%6c%6d%73%63%6f%74%74%62%6f%6f%6b%73%68%6f%70%2e%63%6f%6d%22%3e%69%6e%66%6f%40%6b%65%6c%6d%73%63%6f%74%74%62%6f%6f%6b%73%68%6f%70%2e%63%6f%6d%3c%2f%61%3e%27%29%3b')); 1266</script>
1266</li> 1267 </ul> 1268 <div class="share-icons share-icons-lg circle hidden-xs" id="bottom-share"> 1269 <a class="share-icon fb-icon" data-toggle="tooltip" data-placement="top" href="http://www.facebook.com/pages/Baltimore-MD/142614879117082" rel="external" title="Find on Facebook"><span class="sr-only">Find on Facebook</span><span aria-hidden="true" class="fa fa-facebook"></span></a><a class="share-icon instagram-icon" data-toggle="tooltip" data-placement="top" href="https://www.instagram.com/kelmscott_bookshop/" rel="external" title="Follow on Instagram"><span class="sr-only">Follow on Instagram</span><span aria-hidden="true" class="fa fa-instagram"></span></a> </div> 1270 </div> 1271 <div class="col-xs-6 col-sm-3 col-md-3"> 1272 <ul class="list-unstyled links"> 1273 <li><a href="https://www.kelmscottbookshop.com/advSearch.php">Search Our Inventory</a></li> 1274 <li><a href="https://www.kelmscottbookshop.com/browse.php">Browse Categories</a></li> 1275 <li><a href="https://www.kelmscottbookshop.com/new-arrivals.php">New Arrivals</a></li> 1276 <li><a href="https://www.kelmscottbookshop.com/featured.php">Featured Items</a></li> 1277 <li><a href="https://www.kelmscottbookshop.com/WantList.php">Leave a Want</a></li> 1278 <li><a href="https://www.kelmscottbookshop.com/events.php">Events</a></li> 1279 </ul> 1280 </div> 1281 1282 <div class="col-xs-6 col-sm-3 col-md-3"> 1283 <ul class="list-unstyled links"> 1284 <li><a href="https://www.kelmscottbookshop.com/about.php">About Us</a></li> 1285 <li><a href="https://www.kelmscottbookshop.com/contact.php">Contact Us</a></li> 1286 <li><a href="https://www.kelmscottbookshop.com/terms.php">Terms of Sale</a></li> 1287 <li><a href="https://www.kelmscottbookshop.com/privacy.php">Privacy Policy</a></li> 1288 <li><a href="https://www.kelmscottbookshop.com/accessibility.php">Accessibility</a></li> 1289 </ul> 1290 1291 </div> 1292 <div class="col-xs-6 col-sm-3 col-md-3"> 1293 <ul class="list-unstyled links"> 1294 <li><a href="https://www.kelmscottbookshop.com/cart.php">Shopping Cart</a></li> 1295 <li><a href="https://www.kelmscottbookshop.com/myaccount.php">My Account</a></li> 1296 <li><a href="https://www.kelmscottbookshop.com/createAccount.php">Create an Account</a></li> 1297 <li><a href="https://www.kelmscottbookshop.com/reset-password.php">Forgot Password</a></li> 1298 </ul> 1299 </div> 1300 </div> 1301 <div class="share-icons share-icons-lg circle visible-xs" id="bottom-share"> 1302 <a class="share-icon fb-icon" data-toggle="tooltip" data-placement="top" href="http://www.facebook.com/pages/Baltimore-MD/142614879117082" rel="external" title="Find on Facebook"><span class="sr-only">Find on Facebook</span><span aria-hidden="true" class="fa fa-facebook"></span></a><a class="share-icon instagram-icon" data-toggle="tooltip" data-placement="top" href="https://www.instagram.com/kelmscott_bookshop/" rel="external" title="Follow on Instagram"><span class="sr-only">Follow on Instagram</span><span aria-hidden="true" class="fa fa-instagram"></span></a> </div> 1303 <div id="association-logos-footer" class="widget-content"> 1304 <a aria-label="Member of Antiquarian Booksellers' Association of America" href="http://www.abaa.org" target="_blank"><span aria-hidden="true" tabindex="-1" class="assoc-abaa"></span></a> 1305 <a aria-label="Member of International League of Antiquarian Booksellers" href="http://www.ilab.org" target="_blank"><span aria-hidden="true" tabindex="-1" class="assoc-ilab"></span></a> 1306 <a aria-label="Member of Independent Online Booksellers Association" href="http://www.ioba.org" target="_blank"><span aria-hidden="true" tabindex="-1" class="assoc-ioba"></span></a> 1307 <a href="http://krieger.jhu.edu/museums-society/book-arts-baltimore/" target="_blank"><img src="/images/book-arts-logo.png" alt="Book Arts Baltimore"></a> 1308 </div> 1309 1310 </div> 1311 <div class="footer-copyright-container"> 1312 <p class="footer-copyright"> 1313 © 2026 The Kelmscott Bookshop. All rights reserved. <span><a href="https://www.kelmscottbookshop.com/sitemap.php">Site Map</a></span> | <span> 1314 <a href="http://www.bibliopolis.com" target="_blank" title="Site by Bibliopolis"> 1315 Site by Bibliopolis 1316 </a></span> 1317 </p> 1318 </div> 1319 </div> 1320</footer> 1321 1322<div class="modal fade" id="lyr-topic" tabindex="-1" role="dialog" aria-hidden="true"> 1323 <div class="modal-dialog"> 1324 <div class="modal-content"> 1325 <div class="modal-header"> 1326 <button type="button" class="close" data-mdb-dismiss="modal" data-dismiss="modal">×</button> 1327 <h2>I'd like to be notified of new arrivals in the following categories.</h2> <h3>Check all categories that are of interest to you.</h3> </div> 1328 <div class="modal-body text-center"> 1329 <span aria-hidden="true" tabindex="-1" class="fa fa-2x fa-spinner fa-spin"></span> 1330 </div> 1331 </div> 1332 </div> 1333</div> 1334<div class="modal fade cart-modal book-modal" id="gift_wrap_modal" tabindex="-1" role="dialog" aria-hidden="true"> 1335 <div class="modal-dialog"> 1336 <div class="modal-content"> 1337 <div class="modal-body text-center"> 1338 <span aria-hidden="true" tabindex="-1" class="fa fa-2x fa-spinner fa-spin"></span> 1339 </div> 1340 </div> 1341 </div> 1342</div> 1343<div class="modal fade cart-modal" id="edit_cart_modal" tabindex="-1" role="dialog" aria-hidden="true"> 1344 <div class="modal-dialog"> 1345 <div class="modal-content"> 1346 <div class="modal-body text-center"> 1347 <span aria-hidden="true" tabindex="-1" class="fa fa-2x fa-spinner fa-spin"></span> 1348 </div> 1349 </div> 1350 </div> 1351</div> 1352<div class="modal fade cart-modal" id="login_modal" tabindex="-1" role="dialog" aria-hidden="true"> 1353 <div class="modal-dialog"> 1354 <div class="modal-content"> 1355 <div class="modal-body text-center"> 1356 <span aria-hidden="true" tabindex="-1" class="fa fa-2x fa-spinner fa-spin"></span> 1357 </div> 1358 </div> 1359 </div> 1360</div> 1361 1362<div class="modal fade book-modal" id="add_to_cart_modal" tabindex="-1" role="dialog" aria-hidden="true"></div> 1363 1364<div class="modal cart-modal fade" id="manage_address_modal" tabindex="-1" role="dialog" aria-hidden="true" aria-label="Manage Address"></div> 1365<div class="modal cart-modal fade" id="manage_payment_modal" tabindex="-1" role="dialog" aria-hidden="true" aria-label="Manage Payment"></div> 1366 1367<div class="modal fade" id="search_tips_modal" tabindex="-1" role="dialog" aria-hidden="true"></div> 1368<div class="modal fade" id="coupon_rules_modal" tabindex="-1" role="dialog" aria-hidden="true"></div> 1369<div class="modal fade" id="cvv_modal" tabindex="-1" role="dialog" aria-hidden="true"></div> 1370<div class="modal fade" id="order_history_modal" tabindex="-1" role="dialog" aria-label="Order Details" aria-hidden="true"></div> 1371<div class="modal fade" id="print_modal" tabindex="-1" role="dialog" aria-hidden="true"></div> 1372<div class="modal fade" id="currencies" tabindex="-1" role="dialog" aria-hidden="true"></div> 1373</div> 1374 1375
1376<script src="/manager/include/scripts/bootstrap-accessibility.min.js?v=2" defer></script>
1376 1377 1378 1379</body> 1380</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.