PageSourceSearch

https://www.bookwritinginc.com/assets/js/functions.js?v=1790939144

js bookwritinginc.com collected 2026-10-02 11:05:52 UTC 48,113 bytes, 1,499 lines download raw bytes

1
2(function($) {
3
4    var useWindow = window;
5    
6     if (!Object.keys) {
7        Object.keys = (function() {
8            'use strict';
9            var hasOwnProperty = Object.prototype.hasOwnProperty,
10                    hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
11                    dontEnums = [
12                        'toString',
13                        'toLocaleString',
14                        'valueOf',
15                        'hasOwnProperty',
16                        'isPrototypeOf',
17                        'propertyIsEnumerable',
18                        'constructor'
19                    ],
20                    dontEnumsLength = dontEnums.length;
21
22            return function(obj) {
23                if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
24                    throw new TypeError('Object.keys called on non-object');
25                }
26
27                var result = [], prop, i;
28
29                for (prop in obj) {
30                    if (hasOwnProperty.call(obj, prop)) {
31                        result.push(prop);
32                    }
33                }
34
35                if (hasDontEnumBug) {
36                    for (i = 0; i < dontEnumsLength; i++) {
37                        if (hasOwnProperty.call(obj, dontEnums[i])) {
38                            result.push(dontEnums[i]);
39                        }
40                    }
41                }
42                return result;
43            };
44        }());
45    }
46    
47    // Used to disable some features on IE8
48    var limited_mode = false;
49    var tick_duration = 200; // in ms
50    
51    var debug = (location.hash === "#debug");
52    function debug_log(msg) {
53        if (debug) {
54            console.log(msg);
55        }
56    }
57
58    var allUnits = ["Days", "Hours", "Minutes", "Seconds"];
59    var nextUnits = {
60        Seconds: "Minutes",
61        Minutes: "Hours",
62        Hours: "Days",
63        Days: "Years"
64    };
65    var secondsIn = {
66        Seconds: 1,
67        Minutes: 60,
68        Hours: 3600,
69        Days: 86400,
70        Months: 2678400,
71        Years: 31536000
72    };
73
74    /**
75     * Converts hex color code into object containing integer values for the r,g,b use
76     * This function (hexToRgb) originates from:
77     * http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
78     * @param {string} hex color code
79     */
80    function hexToRgb(hex) {
81
82        // Verify already RGB (e.g. "rgb(0,0,0)") or RGBA (e.g. "rgba(0,0,0,0.5)")
83        var rgba = /^rgba?\(([\d]+),([\d]+),([\d]+)(,([\d\.]+))?\)$/;
84        if(rgba.test(hex)) {
85            var result = rgba.exec(hex);
86            return {
87                r: parseInt(result[1]),
88                g: parseInt(result[2]),
89                b: parseInt(result[3]),
90                a: parseInt(result[5] ? result[5] : 1)
91            };
92        }
93
94        // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
95        var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
96        hex = hex.replace(shorthandRegex, function(m, r, g, b) {
97            return r + r + g + g + b + b;
98        });
99
100        var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
101        return result ? {
102            r: parseInt(result[1], 16),
103            g: parseInt(result[2], 16),
104            b: parseInt(result[3], 16)
105        } : null;
106    }
107    
108    function isCanvasSupported() {
109        var elem = document.createElement('canvas');
110        return !!(elem.getContext && elem.getContext('2d'));
111    }
112
113    /**
114     * Function s4() and guid() originate from:
115     * http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
116     */
117    function s4() {
118        return Math.floor((1 + Math.random()) * 0x10000)
119                .toString(16)
120                .substring(1);
121    }
122
123    /**
124     * Creates a unique id
125     * @returns {String}
126     */
127    function guid() {
128        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
129                s4() + '-' + s4() + s4() + s4();
130    }
131
132    /**
133     * Array.prototype.indexOf fallback for IE8
134     * @param {Mixed} mixed
135     * @returns {Number}
136     */
137    if (!Array.prototype.indexOf) {
138        Array.prototype.indexOf = function(elt /*, from*/)
139        {
140            var len = this.length >>> 0;
141
142            var from = Number(arguments[1]) || 0;
143            from = (from < 0)
144                    ? Math.ceil(from)
145                    : Math.floor(from);
146            if (from < 0)
147                from += len;
148
149            for (; from < len; from++)
150            {
151                if (from in this &&
152                        this[from] === elt)
153                    return from;
154            }
155            return -1;
156        };
157    }
158
159    function parse_date(str) {
160        var match = str.match(/^[0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{1,2}:[0-9]{2}:[0-9]{2}$/);
161        if (match !== null && match.length > 0) {
162            var parts = str.split(" ");
163            var date = parts[0].split("-");
164            var time = parts[1].split(":");
165            return new Date(date[0], date[1] - 1, date[2], time[0], time[1], time[2]);
166        }
167        // Fallback for different date formats
168        var d = Date.parse(str);
169        if (!isNaN(d))
170            return d;
171        d = Date.parse(str.replace(/-/g, '/').replace('T', ' '));
172        if (!isNaN(d))
173            return d;
174        // Cant find anything
175        return new Date();
176    }
177
178    function parse_times(diff, old_diff, total_duration, units, floor) {
179        var raw_time = {};
180        var raw_old_time = {};
181        var time = {};
182        var pct = {};
183        var old_pct = {};
184        var old_time = {};
185
186        var greater_unit = null;
187        for(var i = 0; i < units.length; i++) {
188            var unit = units[i];
189            var maxUnits;
190
191            if (greater_unit === null) {
192                maxUnits = total_duration / secondsIn[unit];
193            }
194            else {
195                maxUnits = secondsIn[greater_unit] / secondsIn[unit];
196            }
197
198            var curUnits = (diff / secondsIn[unit]);
199            var oldUnits = (old_diff / secondsIn[unit]);
200            
201            if(floor) {
202                if(curUnits > 0) curUnits = Math.floor(curUnits);
203                else curUnits = Math.ceil(curUnits);
204                if(oldUnits > 0) oldUnits = Math.floor(oldUnits);
205                else oldUnits = Math.ceil(oldUnits);
206            }
207            
208            if (unit !== "Days") {
209                curUnits = curUnits % maxUnits;
210                oldUnits = oldUnits % maxUnits;
211            }
212
213            raw_time[unit] = curUnits;
214            time[unit] = Math.abs(curUnits);
215            raw_old_time[unit] = oldUnits;
216            old_time[unit] = Math.abs(oldUnits);
217            pct[unit] = Math.abs(curUnits) / maxUnits;
218            old_pct[unit] = Math.abs(oldUnits) / maxUnits;
219
220            greater_unit = unit;
221        }
222
223        return {
224            raw_time: raw_time,
225            raw_old_time: raw_old_time,
226            time: time,
227            old_time: old_time,
228            pct: pct,
229            old_pct: old_pct
230        };
231    }
232
233    var TC_Instance_List = {};
234    function updateUsedWindow() {
235        if(typeof useWindow.TC_Instance_List !== "undefined") {
236            TC_Instance_List = useWindow.TC_Instance_List;
237        }
238        else {
239            useWindow.TC_Instance_List = TC_Instance_List;
240        }
241        initializeAnimationFrameHandler(useWindow);
242    };
243    
244    function initializeAnimationFrameHandler(w) {
245        var vendors = ['webkit', 'moz'];
246        for (var x = 0; x < vendors.length && !w.requestAnimationFrame; ++x) {
247            w.requestAnimationFrame = w[vendors[x] + 'RequestAnimationFrame'];
248            w.cancelAnimationFrame = w[vendors[x] + 'CancelAnimationFrame'];
249        }
250
251        if (!w.requestAnimationFrame || !w.cancelAnimationFrame) {
252            w.requestAnimationFrame = function(callback, element, instance) {
253                if (typeof instance === "undefined")
254                    instance = {data: {last_frame: 0}};
255                var currTime = new Date().getTime();
256                var timeToCall = Math.max(0, 16 - (currTime - instance.data.last_frame));
257                var id = w.setTimeout(function() {
258                    callback(currTime + timeToCall);
259                }, timeToCall);
260                instance.data.last_frame = currTime + timeToCall;
261                return id;
262            };
263            w.cancelAnimationFrame = function(id) {
264                clearTimeout(id);
265            };
266        }
267    };
268    
269
270    var TC_Instance = function(element, options) {
271        this.element = element;
272        this.container;
273        this.listeners = null;
274        this.data = {
275            paused: false,
276            last_frame: 0,
277            animation_frame: null,
278            interval_fallback: null,
279            timer: false,
280            total_duration: null,
281            prev_time: null,
282            drawn_units: [],
283            text_elements: {
284                Days: null,
285                Hours: null,
286                Minutes: null,
287                Seconds: null
288            },
289            attributes: {
290                canvas: null,
291                context: null,
292                item_size: null,
293                line_width: null,
294                radius: null,
295                outer_radius: null
296            },
297            state: {
298                fading: {
299                    Days: false,
300                    Hours: false,
301                    Minutes: false,
302                    Seconds: false
303                }
304            }
305        };
306
307        this.config = null;
308        this.setOptions(options);
309        this.initialize();
310    };
311
312    TC_Instance.prototype.clearListeners = function() {
313        this.listeners = { all: [], visible: [] };
314    };
315    
316    TC_Instance.prototype.addTime = function(seconds_to_add) {
317        if(this.data.attributes.ref_date instanceof Date) {
318            var d = this.data.attributes.ref_date;
319            d.setSeconds(d.getSeconds() + seconds_to_add);
320        }
321        else if(!isNaN(this.data.attributes.ref_date)) {
322            this.data.attributes.ref_date += (seconds_to_add * 1000);
323        }
324    };
325    
326    TC_Instance.prototype.initialize = function(clear_listeners) {
327        // Initialize drawn units
328        this.data.drawn_units = [];
329        for(var i = 0; i < Object.keys(this.config.time).length; i++) {
330            var unit = Object.keys(this.config.time)[i];
331            if (this.config.time[unit].show) {
332                this.data.drawn_units.push(unit);
333            }
334        }
335
336        // Avoid stacking
337        $(this.element).children('div.time_circles').remove();
338
339        if (typeof clear_listeners === "undefined")
340            clear_listeners = true;
341        if (clear_listeners || this.listeners === null) {
342            this.clearListeners();
343        }
344        this.container = $("<div>");
345        this.container.addClass('time_circles');
346        this.container.appendTo(this.element);
347        
348        // Determine the needed width and height of TimeCircles
349        var height = this.element.offsetHeight;
350        var width = this.element.offsetWidth;
351        if (height === 0)
352            height = $(this.element).height();
353        if (width === 0)
354            width = $(this.element).width();
355
356        if (height === 0 && width > 0)
357            height = width / this.data.drawn_units.length;
358        else if (width === 0 && height > 0)
359            width = height * this.data.drawn_units.length;
360        
361        // Create our canvas and set it to the appropriate size
362        var canvasElement = document.createElement('canvas');
363        canvasElement.width = width;
364        canvasElement.height = height;
365        
366        // Add canvas elements
367        this.data.attributes.canvas = $(canvasElement);
368        this.data.attributes.canvas.appendTo(this.container);
369        
370        // Check if the browser has browser support
371        var canvasSupported = isCanvasSupported();
372        // If the browser doesn't have browser support, check if explorer canvas is loaded
373        // (A javascript library that adds canvas support to browsers that don't have it)
374        if(!canvasSupported && typeof G_vmlCanvasManager !== "undefined") {
375            G_vmlCanvasManager.initElement(canvasElement);
376            limited_mode = true;
377            canvasSupported = true;
378        }
379        if(canvasSupported) {
380            this.data.attributes.context = canvasElement.getContext('2d');
381        }
382
383        this.data.attributes.item_size = Math.min(width / this.data.drawn_units.length, height);
384        this.data.attributes.line_width = this.data.attributes.item_size * this.config.fg_width;
385        this.data.attributes.radius = ((this.data.attributes.item_size * 0.8) - this.data.attributes.line_width) / 2;
386        this.data.attributes.outer_radius = this.data.attributes.radius + 0.5 * Math.max(this.data.attributes.line_width, this.data.attributes.line_width * this.config.bg_width);
387
388        // Prepare Time Elements
389        var i = 0;
390        for (var key in this.data.text_elements) {
391            if (!this.config.time[key].show)
392                continue;
393
394            var textElement = $("<div>");
395            textElement.addClass('textDiv_' + key);
396            textElement.css("top", Math.round(0.35 * this.data.attributes.item_size));
397            textElement.css("left", Math.round(i++ * this.data.attributes.item_size));
398            textElement.css("width", this.data.attributes.item_size);
399            textElement.appendTo(this.container);
400
401            var headerElement = $("<h4>");
402            headerElement.text(this.config.time[key].text); // Options
403            headerElement.css("font-size", Math.round(this.config.text_size * this.data.attributes.item_size));
404            headerElement.css("line-height", Math.round(this.config.text_size * this.data.attributes.item_size) + "px");
405            headerElement.appendTo(textElement);
406
407            var numberElement = $("<span>");
408            numberElement.css("font-size", Math.round(3 * this.config.text_size * this.data.attributes.item_size));
409            numberElement.css("line-height", Math.round(this.config.text_size * this.data.attributes.item_size) + "px");
410            numberElement.appendTo(textElement);
411
412            this.data.text_elements[key] = numberElement;
413        }
414
415        this.start();
416        if (!this.config.start) {
417            this.data.paused = true;
418        }
419        
420        // Set up interval fallback
421        var _this = this;
422        this.data.interval_fallback = useWindow.setInterval(function(){
423            _this.update.call(_this, true);
424        }, 100);
425    };
426
427    TC_Instance.prototype.update = function(nodraw) {
428        if(typeof nodraw === "undefined") {
429            nodraw = false;
430        }
431        else if(nodraw && this.data.paused) {
432            return;
433        }
434        
435        if(limited_mode) {
436            //Per unit clearing doesn't work in IE8 using explorer canvas, so do it in one time. The downside is that radial fade cant be used
437            this.data.attributes.context.clearRect(0, 0, this.data.attributes.canvas[0].width, this.data.attributes.canvas[0].hright);
438        }
439        var diff, old_diff;
440
441        var prevDate = this.data.prev_time;
442        var curDate = new Date();
443        this.data.prev_time = curDate;
444
445        if (prevDate === null)
446            prevDate = curDate;
447
448        // If not counting past zero, and time < 0, then simply draw the zero point once, and call stop
449        if (!this.config.count_past_zero) {
450            if (curDate > this.data.attributes.ref_date) {
451                for(var i = 0; i < this.data.drawn_units.length; i++) {
452                    var key = this.data.drawn_units[i];
453
454                    // Set the text value
455                    this.data.text_elements[key].text("0");
456                    var x = (i * this.data.attributes.item_size) + (this.data.attributes.item_size / 2);
457                    var y = this.data.attributes.item_size / 2;
458                    var color = this.config.time[key].color;
459                    this.drawArc(x, y, color, 0);
460                }
461                this.stop();
462                return;
463            }
464        }
465
466        // Compare current time with reference
467        diff = (this.data.attributes.ref_date - curDate) / 1000;
468        old_diff = (this.data.attributes.ref_date - prevDate) / 1000;
469
470        var floor = this.config.animation !== "smooth";
471
472        var visible_times = parse_times(diff, old_diff, this.data.total_duration, this.data.drawn_units, floor);
473        var all_times = parse_times(diff, old_diff, secondsIn["Years"], allUnits, floor);
474
475        var i = 0;
476        var j = 0;
477        var lastKey = null;
478
479        var cur_shown = this.data.drawn_units.slice();
480        for (var i in allUnits) {
481            var key = allUnits[i];
482
483            // Notify (all) listeners
484            if (Math.floor(all_times.raw_time[key]) !== Math.floor(all_times.raw_old_time[key])) {
485                this.notifyListeners(key, Math.floor(all_times.time[key]), Math.floor(diff), "all");
486            }
487
488            if (cur_shown.indexOf(key) < 0)
489                continue;
490
491            // Notify (visible) listeners
492            if (Math.floor(visible_times.raw_time[key]) !== Math.floor(visible_times.raw_old_time[key])) {
493                this.notifyListeners(key, Math.floor(visible_times.time[key]), Math.floor(diff), "visible");
494            }
495            
496            if(!nodraw) {
497                // Set the text value
498                this.data.text_elements[key].text(Math.floor(Math.abs(visible_times.time[key])));
499
500                var x = (j * this.data.attributes.item_size) + (this.data.attributes.item_size / 2);
501                var y = this.data.attributes.item_size / 2;
502                var color = this.config.time[key].color;
503
504                if (this.config.animation === "smooth") {
505                    if (lastKey !== null && !limited_mode) {
506                        if (Math.floor(visible_times.time[lastKey]) > Math.floor(visible_times.old_time[lastKey])) {
507                            this.radialFade(x, y, color, 1, key);
508                            this.data.state.fading[key] = true;
509                        }
510                        else if (Math.floor(visible_times.time[lastKey]) < Math.floor(visible_times.old_time[lastKey])) {
511                            this.radialFade(x, y, color, 0, key);
512                            this.data.state.fading[key] = true;
513                        }
514                    }
515                    if (!this.data.state.fading[key]) {
516                        this.drawArc(x, y, color, visible_times.pct[key]);
517                    }
518                }
519                else {
520                    this.animateArc(x, y, color, visible_times.pct[key], visible_times.old_pct[key], (new Date()).getTime() + tick_duration);
521                }
522            }
523            lastKey = key;
524            j++;
525        }
526
527        // Dont request another update if we should be paused
528        if(this.data.paused || nodraw) {
529            return;
530        }
531        
532        // We need this for our next frame either way
533        var _this = this;
534        var update = function() {
535            _this.update.call(_this);
536        };
537
538        // Either call next update immediately, or in a second
539        if (this.config.animation === "smooth") {
540            // Smooth animation, Queue up the next frame
541            this.data.animation_frame = useWindow.requestAnimationFrame(update, _this.element, _this);
542        }
543        else {
544            // Tick animation, Don't queue until very slightly after the next second happens
545            var delay = (diff % 1) * 1000;
546            if (delay < 0)
547                delay = 1000 + delay;
548            delay += 50;
549
550            _this.data.animation_frame = useWindow.setTimeout(function() {
551                _this.data.animation_frame = useWindow.requestAnimationFrame(update, _this.element, _this);
552            }, delay);
553        }
554    };
555
556    TC_Instance.prototype.animateArc = function(x, y, color, target_pct, cur_pct, animation_end) {
557        if (this.data.attributes.context === null)
558            return;
559
560        var diff = cur_pct - target_pct;
561        if (Math.abs(diff) > 0.5) {
562            if (target_pct === 0) {
563                this.radialFade(x, y, color, 1);
564            }
565            else {
566                this.radialFade(x, y, color, 0);
567            }
568        }
569        else {
570            var progress = (tick_duration - (animation_end - (new Date()).getTime())) / tick_duration;
571            if (progress > 1)
572                progress = 1;
573
574            var pct = (cur_pct * (1 - progress)) + (target_pct * progress);
575            this.drawArc(x, y, color, pct);
576
577            //var show_pct =
578            if (progress >= 1)
579                return;
580            var _this = this;
581            useWindow.requestAnimationFrame(function() {
582                _this.animateArc(x, y, color, target_pct, cur_pct, animation_end);
583            }, this.element);
584        }
585    };
586
587    TC_Instance.prototype.drawArc = function(x, y, color, pct) {
588        if (this.data.attributes.context === null)
589            return;
590
591        var clear_radius = Math.max(this.data.attributes.outer_radius, this.data.attributes.item_size / 2);
592        if(!limited_mode) {
593            this.data.attributes.context.clearRect(
594                    x - clear_radius,
595                    y - clear_radius,
596                    clear_radius * 2,
597                    clear_radius * 2
598                    );
599        }
600        
601        if (this.config.use_background) {
602            this.data.attributes.context.beginPath();
603            this.data.attributes.context.arc(x, y, this.data.attributes.radius, 0, 2 * Math.PI, false);
604            this.data.attributes.context.lineWidth = this.data.attributes.line_width * this.config.bg_width;
605
606            // line color
607            this.data.attributes.context.strokeStyle = this.config.circle_bg_color;
608            this.data.attributes.context.stroke();
609        }
610
611        // Direction
612        var startAngle, endAngle, counterClockwise;
613        var defaultOffset = (-0.5 * Math.PI);
614        var fullCircle = 2 * Math.PI;
615        startAngle = defaultOffset + (this.config.start_angle / 360 * fullCircle);
616        var offset = (2 * pct * Math.PI);
617
618        if (this.config.direction === "Both") {
619            counterClockwise = false;
620            startAngle -= (offset / 2);
621            endAngle = startAngle + offset;
622        }
623        else {
624            if (this.config.direction === "Clockwise") {
625                counterClockwise = false;
626                endAngle = startAngle + offset;
627            }
628            else {
629                counterClockwise = true;
630                endAngle = startAngle - offset;
631            }
632        }
633
634        this.data.attributes.context.beginPath();
635        this.data.attributes.context.arc(x, y, this.data.attributes.radius, startAngle, endAngle, counterClockwise);
636        this.data.attributes.context.lineWidth = this.data.attributes.line_width;
637
638        // line color
639        this.data.attributes.context.strokeStyle = color;
640        this.data.attributes.context.stroke();
641    };
642
643    TC_Instance.prototype.radialFade = function(x, y, color, from, key) {
644        // TODO: Make fade_time option
645        var rgb = hexToRgb(color);
646        var _this = this; // We have a few inner scopes here that will need access to our instance
647
648        var step = 0.2 * ((from === 1) ? -1 : 1);
649        var i;
650        for (i = 0; from <= 1 && from >= 0; i++) {
651            // Create inner scope so our variables are not changed by the time the Timeout triggers
652            (function() {
653                var delay = 50 * i;
654                var rgba = "rgba(" + rgb.r + ", " + rgb.g + ", " + rgb.b + ", " + (Math.round(from * 10) / 10) + ")";
655                useWindow.setTimeout(function() {
656                    _this.drawArc(x, y, rgba, 1);
657                }, delay);
658            }());
659            from += step;
660        }
661        if (typeof key !== undefined) {
662            useWindow.setTimeout(function() {
663                _this.data.state.fading[key] = false;
664            }, 50 * i);
665        }
666    };
667
668    TC_Instance.prototype.timeLeft = function() {
669        if (this.data.paused && typeof this.data.timer === "number") {
670            return this.data.timer;
671        }
672        var now = new Date();
673        return ((this.data.attributes.ref_date - now) / 1000);
674    };
675
676    TC_Instance.prototype.start = function() {
677        useWindow.cancelAnimationFrame(this.data.animation_frame);
678        useWindow.clearTimeout(this.data.animation_frame)
679
680        // Check if a date was passed in html attribute or jquery data
681        var attr_data_date = $(this.element).data('date');
682        if (typeof attr_data_date === "undefined") {
683            attr_data_date = $(this.element).attr('data-date');
684        }
685        if (typeof attr_data_date === "string") {
686            this.data.attributes.ref_date = parse_date(attr_data_date);
687        }
688        // Check if this is an unpause of a timer
689        else if (typeof this.data.timer === "number") {
690            if (this.data.paused) {
691                this.data.attributes.ref_date = (new Date()).getTime() + (this.data.timer * 1000);
692            }
693        }
694        else {
695            // Try to get data-timer
696            var attr_data_timer = $(this.element).data('timer');
697            if (typeof attr_data_timer === "undefined") {
698                attr_data_timer = $(this.element).attr('data-timer');
699            }
700            if (typeof attr_data_timer === "string") {
701                attr_data_timer = parseFloat(attr_data_timer);
702            }
703            if (typeof attr_data_timer === "number") {
704                this.data.timer = attr_data_timer;
705                this.data.attributes.ref_date = (new Date()).getTime() + (attr_data_timer * 1000);
706            }
707            else {
708                // data-timer and data-date were both not set
709                // use config date
710                this.data.attributes.ref_date = this.config.ref_date;
711            }
712        }
713
714        // Start running
715        this.data.paused = false;
716        this.update.call(this);
717    };
718
719    TC_Instance.prototype.restart = function() {
720        this.data.timer = false;
721        this.start();
722    };
723
724    TC_Instance.prototype.stop = function() {
725        if (typeof this.data.timer === "number") {
726            this.data.timer = this.timeLeft(this);
727        }
728        // Stop running
729        this.data.paused = true;
730        useWindow.cancelAnimationFrame(this.data.animation_frame);
731    };
732
733    TC_Instance.prototype.destroy = function() {
734        this.clearListeners();
735        this.stop();
736        useWindow.clearInterval(this.data.interval_fallback);
737        this.data.interval_fallback = null;
738        
739        this.container.remove();
740        $(this.element).removeAttr('data-tc-id');
741        $(this.element).removeData('tc-id');
742    };
743
744    TC_Instance.prototype.setOptions = function(options) {
745        if (this.config === null) {
746            this.default_options.ref_date = new Date();
747            this.config = $.extend(true, {}, this.default_options);
748        }
749        $.extend(true, this.config, options);
750
751        // Use window.top if use_top_frame is true
752        if(this.config.use_top_frame) {
753            useWindow = window.top;
754        }
755        else {
756            useWindow = window;
757        }
758        updateUsedWindow();
759        
760        this.data.total_duration = this.config.total_duration;
761        if (typeof this.data.total_duration === "string") {
762            if (typeof secondsIn[this.data.total_duration] !== "undefined") {
763                // If set to Years, Months, Days, Hours or Minutes, fetch the secondsIn value for that
764                this.data.total_duration = secondsIn[this.data.total_duration];
765            }
766            else if (this.data.total_duration === "Auto") {
767                // If set to auto, total_duration is the size of 1 unit, of the unit type bigger than the largest shown
768                for(var i = 0; i < Object.keys(this.config.time).length; i++) {
769                    var unit = Object.keys(this.config.time)[i];
770                    if (this.config.time[unit].show) {
771                        this.data.total_duration = secondsIn[nextUnits[unit]];
772                        break;
773                    }
774                }
775            }
776            else {
777                // If it's a string, but neither of the above, user screwed up.
778                this.data.total_duration = secondsIn["Years"];
779                console.error("Valid values for TimeCircles config.total_duration are either numeric, or (string) Years, Months, Days, Hours, Minutes, Auto");
780            }
781        }
782    };
783
784    TC_Instance.prototype.addListener = function(f, context, type) {
785        if (typeof f !== "function")
786            return;
787        if (typeof type === "undefined")
788            type = "visible";
789        this.listeners[type].push({func: f, scope: context});
790    };
791
792    TC_Instance.prototype.notifyListeners = function(unit, value, total, type) {
793        for (var i = 0; i < this.listeners[type].length; i++) {
794            var listener = this.listeners[type][i];
795            listener.func.apply(listener.scope, [unit, value, total]);
796        }
797    };
798
799    TC_Instance.prototype.default_options = {
800        ref_date: new Date(),
801        start: true,
802        animation: "smooth",
803        count_past_zero: true,
804        circle_bg_color: "#60686F",
805        use_background: true,
806        fg_width: 0.1,
807        bg_width: 1.2,
808        text_size: 0.07,
809        total_duration: "Auto",
810        direction: "Clockwise",
811        use_top_frame: false,
812        start_angle: 0,
813        time: {
814            Days: {
815                show: true,
816                text: "Days",
817                color: "#FC6"
818            },
819            Hours: {
820                show: true,
821                text: "Hours",
822                color: "#9CF"
823            },
824            Minutes: {
825                show: true,
826                text: "Minutes",
827                color: "#BFB"
828            },
829            Seconds: {
830                show: true,
831                text: "Seconds",
832                color: "#F99"
833            }
834        }
835    };
836
837    // Time circle class
838    var TC_Class = function(elements, options) {
839        this.elements = elements;
840        this.options = options;
841        this.foreach();
842    };
843
844    TC_Class.prototype.getInstance = function(element) {
845        var instance;
846
847        var cur_id = $(element).data("tc-id");
848        if (typeof cur_id === "undefined") {
849            cur_id = guid();
850            $(element).attr("data-tc-id", cur_id);
851        }
852        if (typeof TC_Instance_List[cur_id] === "undefined") {
853            var options = this.options;
854            var element_options = $(element).data('options');
855            if (typeof element_options === "string") {
856                element_options = JSON.parse(element_options);
857            }
858            if (typeof element_options === "object") {
859                options = $.extend(true, {}, this.options, element_options);
860            }
861            instance = new TC_Instance(element, options);
862            TC_Instance_List[cur_id] = instance;
863        }
864        else {
865            instance = TC_Instance_List[cur_id];
866            if (typeof this.options !== "undefined") {
867                instance.setOptions(this.options);
868            }
869        }
870        return instance;
871    };
872
873    TC_Class.prototype.addTime = function(seconds_to_add) {
874        this.foreach(function(instance) {
875            instance.addTime(seconds_to_add);
876        });
877    };
878    
879    TC_Class.prototype.foreach = function(callback) {
880        var _this = this;
881        this.elements.each(function() {
882            var instance = _this.getInstance(this);
883            if (typeof callback === "function") {
884                callback(instance);
885            }
886        });
887        return this;
888    };
889
890    TC_Class.prototype.start = function() {
891        this.foreach(function(instance) {
892            instance.start();
893        });
894        return this;
895    };
896
897    TC_Class.prototype.stop = function() {
898        this.foreach(function(instance) {
899            instance.stop();
900        });
901        return this;
902    };
903
904    TC_Class.prototype.restart = function() {
905        this.foreach(function(instance) {
906            instance.restart();
907        });
908        return this;
909    };
910
911    TC_Class.prototype.rebuild = function() {
912        this.foreach(function(instance) {
913            instance.initialize(false);
914        });
915        return this;
916    };
917
918    TC_Class.prototype.getTime = function() {
919        return this.getInstance(this.elements[0]).timeLeft();
920    };
921
922    TC_Class.prototype.addListener = function(f, type) {
923        if (typeof type === "undefined")
924            type = "visible";
925        var _this = this;
926        this.foreach(function(instance) {
927            instance.addListener(f, _this.elements, type);
928        });
929        return this;
930    };
931
932    TC_Class.prototype.destroy = function() {
933        this.foreach(function(instance) {
934            instance.destroy();
935        });
936        return this;
937    };
938
939    TC_Class.prototype.end = function() {
940        return this.elements;
941    };
942
943    $.fn.TimeCircles = function(options) {
944        return new TC_Class(this, options);
945    };
946}(jQuery));
947
948
949
950
951
952
953 $(function(){
954		 $("#CountDownTimer").TimeCircles({ time: { Days: { show: false }, Hours: { show: true } }
955		 });
956		  });
957
958
959
960$(document).ready(function() {
961	
962	
963var newsletter_p = setInterval(function(){
964$("#ouibounce-modal").css("display","block")
965$("body").addClass('fixed');
966clearInterval(newsletter_p);
967},5000); 
968
969$('.cus-overlay').click(function(){
970	$('#ouibounce-modal2').attr('id' , 'ouibounce-modal' );
971	setTimeout(function(){ $('#ouibounce-modal').css('display' , 'block' )}, 5000);
972
973});
974$('.popup-form .close').click(function(){
975	$('#ouibounce-modal2').attr('id' , 'ouibounce-modal' );
976	
977	setTimeout(function(){ $('#ouibounce-modal').css('display' , 'block' )}, 5000);
978
979});
980
981
982$('div#btmsticky a.various, .various, a.view-pricing-txt.various, img.bn-2').click(function(){
983	$('#ouibounce-modal').attr('id' , 'ouibounce-modal2' );
984
985});
986
987    
988 $('.modal-footer a, .underlay').click( function(){
989	 $("body").removeClass('fixed');
990
991 });
992		
993
994$(window).scroll(function(){
995		
996	
997			var headerHeight = 300-140; 
998			if ( ( $(window).scrollTop() >= headerHeight  ) ){
999				$('.floating-form-wrap, .side-bars').fadeIn( 300 );
1000				$('.floating-banner').fadeIn(300);
1001				$('.btm-sticky').fadeIn(300);
1002			}
1003			else {
1004				$('.floating-form-wrap, .side-bars').fadeOut( 300 );
1005				$('.floating-banner').fadeOut(300);
1006				$('.btm-sticky').fadeOut(300);
1007			}
1008		
1009	});//window scroll end
1010
1011
1012$('.lead_price').click(function(){
1013        $('<input>').attr({
1014    type: 'hidden',
1015    value: '-',
1016    id: 'lead_p',
1017    name: 'lead_p'
1018}).appendTo('#popupform form');
1019   });
1020  
1021$('.lead_price2').click(function(){
1022        $('<input>').attr({
1023    type: 'hidden',
1024    value: 'New-',
1025    id: 'lead_p',
1026    name: 'lead_p'
1027}).appendTo('#popupform form');
1028   });
1029   
1030   $('.close, .cus-overlay').click(function(){
1031	  $("#popupform form").find("#lead_p").remove();
1032
1033
1034});
1035
1036      $(".view-pricing-txt").click(function(){
1037        var pkgname2=$(this).attr('title');
1038       
1039         if ( $(this).attr('title') !== undefined)
1040            {
1041                $('.popupform h3, .popupform h2').html(pkgname2);
1042				$('#textC').html(pkgname2);
1043
1044                 return;
1045            }
1046          else {
1047            var pkgname2=$(this).attr('title');
1048					$('#lead_pkg_name').html("REQUEST FREE CONSULTATION");
1049					$('#textC').html("REQUEST FREE CONSULTATION");
1050
1051          
1052            }
1053        });
1054		
1055		
1056		
1057		
1058		
1059$('[data-fancybox]').fancybox();
1060$(".validate-footer").validate();
1061$(".validate-popup").validate();
1062$(".validate-contact").validate();
1063$(".validate-opt").validate();
1064$(".validate-lpform").validate();
1065
1066 
1067 
1068
1069$('.various, div#btmsticky a.various, img.bn-2').click( function(){
1070	$("body").addClass('fixed');
1071	$('.popupform').show(300).addClass('visibleit');
1072	$('.cus-overlay').fadeIn(300);
1073});
1074
1075$('a.various2').click( function(){
1076	$("body").addClass('fixed');
1077	$('.popfrm').show(300).addClass('visibleit');
1078	$('.cus-overlay').fadeIn(300);
1079});
1080
1081
1082
1083
1084
1085$('.cus-overlay, .close').click( function(){
1086		$("body").removeClass('fixed');
1087		$('.popupform').css({'overflow':'hidden'})
1088		$('.popupform').hide(300);
1089		$('.cus-overlay').fadeOut(300)
1090		$(this).fadeOut(300);
1091	});
1092	
1093	
1094
1095
1096
1097 
1098
1099
1100window.__lc = window.__lc || {};
1101window.__lc.license = 19777042;
1102window.__lc.integration_name = "manual_channels";
1103window.__lc.product_name = "livechat";
1104;(function(n,t,c){function i(n){return e._h?e._h.apply(null,n):e._q.push(n)}var e={_q:[],_h:null,_v:"2.0",on:function(){i(["on",c.call(arguments)])},once:function(){i(["once",c.call(arguments)])},off:function(){i(["off",c.call(arguments)])},get:function(){if(!e._h)throw new Error("[LiveChatWidget] You can't use getters before load.");return i(["get",c.call(arguments)])},call:function(){i(["call",c.call(arguments)])},init:function(){var n=t.createElement("script");n.async=!0,n.type="text/javascript",n.src="https://cdn.livechatinc.com/tracking.js",t.head.appendChild(n)}};!n.__lc.asyncInit&&e.init(),n.LiveChatWidget=n.LiveChatWidget||e}(window,document,[].slice))
1105
1106
1107
1108
1109$('.chat').click( function(){
1110LiveChatWidget.call('maximize'); return false;
1111});
1112
1113
1114
1115 $zopim(function() {
1116    $zopim.livechat.theme.setColors({badge: '#fd7c07', primary: '#fd7c07'});
1117    $zopim.livechat.theme.reload(); // apply new theme settings
1118  });
1119  
1120 /* $zopim(function() {
1121    $zopim.livechat.setGreetings({
1122          'online': 'Chat with us',
1123          'offline': 'Leave us a message'
1124      });
1125  }); */
1126
1127$("li:first-child").addClass("first");
1128$("li:last-child").addClass("last");
1129$("tr:nth-child(odd)").addClass("alter");
1130$('[href="#"]').attr("href", "javascript:;");
1131 
1132});
1133
1134 
1135$( document ).ready(function() {
1136	var currentIP = $("meta[name=ip2loc]").attr('content');
1137	var key = '5XpThOAEkfgOvEJ';
1138	$.ajax({
1139		method: 'get',
1140		url: 'https://pro.ip-api.com/json/' + currentIP,
1141		data: {key: key},
1142		success: function (data) {
1143			if (data) {
1144				$('input[name=ip2loc_ip]').val(data.query);
1145				$('input[name=ip2loc_isp]').val(data.isp);
1146				$('input[name=ip2loc_org]').val(data.org);
1147				$('input[name=ip2loc_country]').val(data.country);
1148				$('input[name=ip2loc_region]').val(data.regionName);
1149				$('input[name=ip2loc_city]').val(data.city);
1150				$('input[name=ip2loc_countryCode]').val(data.countryCode);
1151			}
1152		}
1153	});
1154	
1155	
1156	    var currentIP = $("meta[name=ip2loc]").attr('content');
1157		var iplocactionKey = '5XpThOAEkfgOvEJ';
1158
1159
1160		$(".ftpn").intlTelInput({
1161			autoPlaceholder: true,
1162			defaultCountry: "auto",
1163			initialCountry: "auto",
1164			nationalMode: false,
1165			numberType: "MOBILE",
1166			preventInvalidNumbers: true,
1167			geoIpLookup: function(callback) {
1168				$.get('https://pro.ip-api.com/json/' + currentIP + '?key=' + iplocactionKey, function() {}, 'jsonp').always(function(resp) {
1169					var countryCode = (resp && resp.countryCode) ? resp.countryCode : "";
1170					callback(resp.countryCode);
1171				});
1172			}
1173		}).done(function() {});
1174		
1175		
1176		$('.test-slider').owlCarousel({
1177            loop:true,
1178            margin: 10,
1179            items:1,
1180            nav:false,
1181            autoplay: true,
1182            autoplayTimeout: 2000,
1183            autoplayHoverPause: true
1184        }); 
1185
1186});
1187
1188
1189
1190/* Book Cover Design — jQuery interactions */
1191
1192(function ($) {
1193  "use strict";
1194
1195  function pad(n) {
1196    return n < 10 ? "0" + n : String(n);
1197  }
1198
1199  function setRing($circle, value, max) {
1200    var circumference = 264;
1201    var offset = circumference - (value / max) * circumference;
1202    $circle.css("stroke-dashoffset", offset);
1203  }
1204
1205  function startCountdown() {
1206    var totalSeconds = 5600;
1207
1208    function tick() {
1209      if (totalSeconds < 0) totalSeconds = 5600;
1210
1211      var h = Math.floor(totalSeconds / 3600);
1212      var m = Math.floor((totalSeconds % 3600) / 60);
1213      var s = totalSeconds % 60;
1214
1215      $("#cd-hours").text(pad(h));
1216      $("#cd-minutes").text(pad(m));
1217      $("#cd-seconds").text(pad(s));
1218
1219      setRing($(".progress.hours"), h, 24);
1220      setRing($(".progress.minutes"), m, 60);
1221      setRing($(".progress.seconds"), s, 60);
1222
1223      totalSeconds -= 1;
1224    }
1225
1226    tick();
1227    setInterval(tick, 1000);
1228  }
1229
1230  function revealOnScroll() {
1231    var winBottom = $(window).scrollTop() + $(window).height() * 0.88;
1232
1233    $(".reveal").each(function () {
1234      var $el = $(this);
1235      if (!$el.hasClass("visible") && $el.offset().top < winBottom) {
1236        $el.addClass("visible");
1237
1238        // stagger children inside section
1239        $el.find(".genre-tile, .why-card, .flow-card, .process-step, .icon-pill, .craft-item")
1240          .each(function (i) {
1241            var $child = $(this);
1242            $child.css({
1243              opacity: 0,
1244              transform: "translateY(18px)"
1245            });
1246            setTimeout(function () {
1247              $child.css({
1248                transition: "opacity 0.5s ease, transform 0.5s ease",
1249                opacity: 1,
1250                transform: "translateY(0)"
1251              });
1252            }, 80 + i * 70);
1253          });
1254      }
1255    });
1256  }
1257
1258  function revealBanner() {
1259    $(".reveal-banner").each(function (i) {
1260      var $el = $(this);
1261      setTimeout(function () {
1262        $el.addClass("visible");
1263      }, 80 + i * 90);
1264    });
1265  }
1266
1267  function initFaq() {
1268    $(".faq-item.active .faq-a").show();
1269
1270    $(".faq-q").on("click", function () {
1271      var $item = $(this).closest(".faq-item");
1272      var $answer = $item.find(".faq-a");
1273      var isOpen = $item.hasClass("active");
1274
1275      $(".faq-item").not($item).removeClass("active").find(".faq-a").slide
1275Up(280);
1276      $(".faq-item").not($item).find(".faq-q").attr("aria-expanded", "false");
1277
1278      if (isOpen) {
1279        $item.removeClass("active");
1280        $answer.slideUp(280);
1281        $(this).attr("aria-expanded", "false");
1282      } else {
1283        $item.addClass("active");
1284        $answer.slideDown(280);
1285        $(this).attr("aria-expanded", "true");
1286      }
1287    });
1288  }
1289
1290  function bannerParallax() {
1291    var $banner = $(".n-inner-banner");
1292    if (!$banner.length) return;
1293
1294    $(window).on("scroll", function () {
1295      var scrolled = $(window).scrollTop();
1296      if (scrolled < $banner.outerHeight()) {
1297        $banner.css("background-position", "center " + scrolled * 0.25 + "px");
1298      }
1299    });
1300  }
1301
1302  function initForm() {
1303    $("#bannerForm").on("submit", function (e) {
1304      e.preventDefault();
1305      var $btn = $(this).find(".btn-submit");
1306      var original = $btn.html();
1307      $btn.html('<i class="fa fa-check"></i> Thank You!').prop("disabled", true);
1308      setTimeout(function () {
1309        $btn.html(original).prop("disabled", false);
1310        $("#bannerForm")[0].reset();
1311      }, 2200);
1312    });
1313  }
1314
1315  function imageTilt() {
1316    $(".media-frame, .polaroid, .magazine__art").on("mousemove", function (e) {
1317      var $el = $(this);
1318      var off = $el.offset();
1319      var x = (e.pageX - off.left) / $el.outerWidth();
1320      var y = (e.pageY - off.top) / $el.outerHeight();
1321      var rx = (0.5 - y) * 8;
1322      var ry = (x - 0.5) * 8;
1323      $el.css("transform", "perspective(800px) rotateX(" + rx + "deg) rotateY(" + ry + "deg)");
1324    }).on("mouseleave", function () {
1325      $(this).css("transform", "");
1326    });
1327  }
1328
1329  $(function () {
1330    startCountdown();
1331    revealBanner();
1332    revealOnScroll();
1333    initFaq();
1334    bannerParallax();
1335    initForm();
1336    imageTilt();
1337
1338    $(window).on("scroll resize", revealOnScroll);
1339  });
1340})(jQuery);
1341
1342
1343
1344
1345
1346
1347/* BWI Premium Navigation — unique prefix: bwi-pn- */
1348(function ($) {
1349  "use strict";
1350
1351  var $header = $("#bwiPnHeader");
1352  if (!$header.length) return;
1353
1354  var $wrap = $("#bwiPnWrap");
1355  var $top = $("#bwiPnTop");
1356  var $toggle = $("#bwiPnToggle");
1357  var $scrim = $("#bwiPnScrim");
1358  var $nav = $header.find(".bwi-pn__nav");
1359  var $items = $header.find(".bwi-pn__item--drop");
1360  var mq = window.matchMedia("(max-width: 1024px)");
1361
1362  function isMobile() {
1363    return mq.matches;
1364  }
1365
1366  function closeAllDrops() {
1367    $items.removeClass("is-open");
1368    $items.find(".bwi-pn__drop-btn").attr("aria-expanded", "false");
1369  }
1370
1371  function syncDrawerTop() {
1372    var target = $wrap.length ? $wrap[0] : document.documentElement;
1373    if (!isMobile()) {
1374      target.style.removeProperty("--bwi-pn-drawer-top");
1375      $nav.css({ top: "", bottom: "", maxHeight: "", height: "" });
1376      return;
1377    }
1378    var rect = $header[0].getBoundingClientRect();
1379    var top = Math.max(0, Math.round(rect.bottom));
1380    target.style.setProperty("--bwi-pn-drawer-top", top + "px");
1381  }
1382
1383  function closeDrawer() {
1384    $header.removeClass("is-drawer-open");
1385    $wrap.removeClass("is-drawer-open");
1386    $toggle.attr("aria-expanded", "false").attr("aria-label", "Open menu");
1387    $scrim.attr("hidden", true);
1388    $("body").removeClass("bwi-pn-no-scroll");
1389    closeAllDrops();
1390  }
1391
1392  function openDrawer() {
1393    $header.addClass("is-drawer-open");
1394    $wrap.addClass("is-drawer-open");
1395    // topbar hide ke baad measure — overlay header se start ho
1396    window.requestAnimationFrame(function () {
1397      syncDrawerTop();
1398    });
1399    $toggle.attr("aria-expanded", "true").attr("aria-label", "Close menu");
1400    $scrim.removeAttr("hidden");
1401    $("body").addClass("bwi-pn-no-scroll");
1402  }
1403
1404  $items.each(function () {
1405    var $item = $(this);
1406    var $btn = $item.find("> .bwi-pn__drop-btn");
1407    var hoverTimer;
1408
1409    $item.on("mouseenter", function () {
1410      if (isMobile()) return;
1411      clearTimeout(hoverTimer);
1412      closeAllDrops();
1413      $item.addClass("is-open");
1414      $btn.attr("aria-expanded", "true");
1415    });
1416
1417    $item.on("mouseleave", function () {
1418      if (isMobile()) return;
1419      hoverTimer = setTimeout(function () {
1420        $item.removeClass("is-open");
1421        $btn.attr("aria-expanded", "false");
1422      }, 140);
1423    });
1424
1425    $btn.on("click", function (e) {
1426      e.preventDefault();
1427      e.stopPropagation();
1428      var open = $item.hasClass("is-open");
1429      if (isMobile()) {
1430        $items.not($item).removeClass("is-open")
1431          .find(".bwi-pn__drop-btn").attr("aria-expanded", "false");
1432        $item.toggleClass("is-open", !open);
1433        $btn.attr("aria-expanded", open ? "false" : "true");
1434      } else {
1435        closeAllDrops();
1436        if (!open) {
1437          $item.addClass("is-open");
1438          $btn.attr("aria-expanded", "true");
1439        }
1440      }
1441    });
1442  });
1443
1444  $toggle.on("click", function (e) {
1445    e.preventDefault();
1446    if ($header.hasClass("is-drawer-open")) closeDrawer();
1447    else openDrawer();
1448  });
1449
1450  $scrim.on("click", closeDrawer);
1451
1452  $(document).on("keydown", function (e) {
1453    if (e.key === "Escape") closeDrawer();
1454  });
1455
1456  $(document).on("click", function (e) {
1457    if (!$(e.target).closest(".bwi-pn").length) closeAllDrops();
1458  });
1459
1460  $header.on("click", ".bwi-pn__cols a, .bwi-pn__item:not(.bwi-pn__item--drop) > .bwi-pn__link", function () {
1461    if (isMobile()) closeDrawer();
1462  });
1463
1464  function onBreakpointChange() {
1465    closeDrawer();
1466    syncDrawerTop();
1467  }
1468
1469  if (mq.addEventListener) mq.addEventListener("change", onBreakpointChange);
1470  else if (mq.addListener) mq.addListener(onBreakpointChange);
1471
1472  if ("IntersectionObserver" in window && $top.length) {
1473    var io = new IntersectionObserver(
1474      function (entries) {
1475        $header.toggleClass("bwi-pn--scrolled", !entries[0].isIntersecting);
1476      },
1477      { root: null, threshold: 0 }
1478    );
1479    io.observe($top[0]);
1480  } else {
1481    var ticking = false;
1482    $(window).on("scroll", function () {
1483      if (ticking) return;
1484      ticking = true;
1485      window.requestAnimationFrame(function () {
1486        var past = $top.length
1487          ? $top[0].getBoundingClientRect().bottom <= 0
1488          : $(window).scrollTop() > 8;
1489        $header.toggleClass("bwi-pn--scrolled", past);
1490        ticking = false;
1491      });
1492    });
1493  }
1494
1495  $(window).on("resize orientationchange", function () {
1496    if ($header.hasClass("is-drawer-open")) syncDrawerTop();
1497  });
1498})(jQuery);
1499

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.