PageSourceSearch

https://taiwanfriend.com/scripts/scripts.js?88445ab&5

js taiwanfriend.com collected 2026-09-26 08:12:12 UTC 17,197 bytes, 537 lines download raw bytes

1var app = app || {};
2var slider = slider || {};
3if (!window.console) window.console = {};
4if (!window.console.log) window.console.log = function() {};
5var $document = $(document),
6    $window = $(window),
7    $html = $('html'),
8    $body = $('body'),
9    $htmlbody = $('html,body'),
10    transitionEnd = 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend';
11desktop = Detectizr.device.type == 'desktop';
12var $main = $('#main'),
13    $countersBtn = $('.counters-btn'),
14    $logo = $('#logo'),
15    $login = $('.LoginIndex'),
16    $loginLink = $('.LoginIndex .common'),
17    $localeLink = $('.SwitchLocale'),
18    $loaderBg = $('#loader-bg'),
19    $navLabel = $('.nav-label'),
20    $dots = $('.dot'),
21    $dotClone = $('#dot'),
22    $title = $('#title'),
23    $btnNext = $('#btn-next'),
24    $navLinks = $('.nav-link'),
25    $projects = $('.project'),
26    $registration = $('.Registration'),
27    $registrationTitle = $('.registration-title'),
28    $reglinkMobile = $('.reglink-for-mob'),
29    $overlays = $('.project-overlay'),
30    $masks = $('.project-mask'),
31    $contents = $('.project-content'),
32    _direction = null,
33    _dotPos = null,
34    _current = null,
35    _prev = null,
36    _next = null,
37    _total = null,
38    _lastAnim = 0,
39    _delay = 500,
40    _duration = 1000,
41    _colors = null,
42    _prevColors = null;
43var myVar;
44TweenLite.defaultEase = Expo.easeInOut;
45
46var regformup = true,
47    locale = false,
48    loginformIs = false;
49
50function hideLoginForm() {
51    if (loginformIs) {
52        $(".LoginIndex .expand-block").hide(400);
53        $login.removeClass("expanded");
54        if ($(document).width() < 481) {
55            $login.removeClass("mobile-expanded");
56        }
57        $('.LoginIndex input').each(function(){
58            $(this).removeClass('invalid');
59        });
60        loginformIs = false;
61    }
62}
63
64app.init = function(parent, children) {
65    $('a[href="#"]').on('click', function(e) {
66        e.preventDefault();
67    });
68    if (Detectizr.device.model === 'mac') {
69        $html.addClass('is-mac');
70    }
71    var bLazyOptions = {
72        selector: '.lazy',
73        offset: 100,
74        successClass: 'is-loaded',
75        breakpoints: [{
76            width: 1440,
77            src: 'data-src-larger'
78        }, {
79            width: 1280,
80            src: 'data-src-large'
81        }, {
82            width: 1024,
83            src: 'data-src-normal'
84        }, {
85            width: 768,
86            src: 'data-src-medium'
87        }, {
88            width: 480,
89            src: 'data-src-small'
90        }]
91    };
92    var bLazy = new Blazy(bLazyOptions);
93
94    $window.on('load', function() {
95        app.loader();
96        bLazy.revalidate();
97    });
98    if (desktop) {
99        slider.init();
100
101        $navLinks.each(function(i, e) {
102            var $this = $(this);
103            $this.on('click', function(e) {
104                e.preventDefault();
105                var dir = i > _current ? 'next' : 'prev';
106                slider.slide(i, dir);
107            });
108        });
109
110        $btnNext.on('click', function() {
111            var index = _current + 1 <= _total ? _current + 1 : 0;
112            slider.slide(index, 'next');
113        });
114
115        //$document.bind('keyup', app.keyNav);
116        if ($window.outerWidth() < 1025) {
117            $document.unbind('mousewheel DOMMouseScroll', app.scrollNav);
118        } else {
119            $document.bind('mousewheel DOMMouseScroll', app.scrollNav);
120        }
121        $window.on('resize', function() {
122            if ($window.outerWidth() < 1025) {
123                $document.unbind('mousewheel DOMMouseScroll', app.scrollNav);
124            } else {
125                $document.bind('mousewheel DOMMouseScroll', app.scrollNav);
126            }
127        });
128    }
129    $countersBtn.each(function(i, e) {
130        var $this = $(this);
131        $this.on('click', function(e) {
132            e.preventDefault();
133            if ($window.outerWidth() > 1024) {
134                slider.slide(0, 'next');
135            }
136            else {
137                $htmlbody.animate({scrollTop: $registrationTitle.offset().top}, 500);
138                $registration.show(600);
139                hideLoginForm();
140                if (locale)
141                {
142                    $(".SwitchLocale .highlighted").hide(400);
143                    locale = false;
144                }
145                regformup = true;
146                $reglinkMobile.hide();
147            }
148        });
149    });
150};
151app.loader = function() {
152    if (desktop) {
153        TweenLite.set($loaderBg, {
154            scaleX: (viewWidth * 2 / $loaderBg.width()) + 1,
155            scaleY: (viewHeight / $loaderBg.height()) + 1
156        });
157    }
158    if (!Modernizr.csstransitions) {
159        TweenLite.to($loaderBg, 1, {
160            scaleX: 1,
161            scaleY: 1,
162            onComplete: function() {
163                setTimeout(function() {
164                    $html.addClass('is-loaded');
165                }, 1000);
166            }
167        });
168    } else {
169        setTimeout(function() {
170            $html.addClass('is-loaded');
171        }, 1000);
172    }
173};
174app.keyNav = function(event) {
175    if (event.which === 40 || event.which === 39) {
176        index = _current + 1 <= _total ? _current + 1 : 0;
177        slider.slide(index, 'next');
178    }
179    if (event.which === 38 || event.which === 37) {
180        index = _current - 1 >= 0 ? _current - 1 : _total;
181        slider.slide(index, 'prev');
182    }
183};
184app.scrollNav = function(event) {
185    event.preventDefault();
186    var t = event.originalEvent.wheelDelta || -event.originalEvent.detail;
187    var n = (new Date()).getTime();
188    if (n - _lastAnim < _delay + _duration) {
189        event.preventDefault();
190        return;
191    }
192    if (t < 0) {
193        i = _current + 1 <= _total ? _current + 1 : 0;
194        slider.slide(i, 'next');
195    } else if (t > 0) {
196        i = _current - 1 >= 0 ? _current - 1 : _total;
197        slider.slide(i, 'prev');
198    }
199    _lastAnim = n;
200};
201slider.init = function() {
202    _current = 0;
203    _prev = -1;
204    _next = 1;
205    _total = $navLinks.length - 1;
206    var $link = $navLinks.eq(_current),
207        $dot = $dots.eq(_current),
208        $project = $projects.eq(_current),
209        $overlay = $overlays.eq(_current),
210        $mask = $masks.eq(_current),
211        $content = $contents.eq(_current);
212    $link.data('active', true).addClass('is-active');
213    $project.data('active', true).addClass('is-active');
214    TweenLite.set($overlay, {
215        y: '0%'
216    });
217    TweenLite.set($mask, {
218        y: '0%'
219    });
220    TweenLite.set($content, {
221        y: '0%'
222    });
223    _dotPos = {};
224    _dotPos.top = $dot.offset().top;
225    _dotPos.left = $dot.offset().left;
226    _dotPos.bottom = $window.outerHeight() - _dotPos.top - $dot.outerHeight();
227    TweenLite.set($dotClone, {
228        scaleX: 0,
229        scaleY: 0.65,
230        top: _dotPos.top + 'px',
231        bottom: _dotPos.bottom
232    });
233    TweenLite.set($dots, {
234        scaleX: 0.65,
235        scaleY: 0.65
236    });
237    TweenLite.set($dot, {
238        scaleX: 1.5,
239        scaleY: 1.5
240    });
241    _prevColors = {
242        bg: $project.data('bg') === undefined ? null : $project.data('bg'),
243        pattern: $project.data('pattern') === undefined ? null : app.hexToRgb($project.data('pattern')),
244        main: $project.data('main') === undefined ? null : app.hexToRgb($project.data('main')),
245        secondary: $project.data('secondary') === undefined ? null : $project.data('secondary'),
246        siteTitle: $project.data('sitetitle') === undefined ? null : app.hexToRgb($project.data('sitetitle')),
247        btnContact: $project.data('btncontact') === undefined ? null : $project.data('btncontact'),
248        logo: $project.data('logo') === undefined ? null : $project.data('logo')
249    };
250    slider.updateColors(_prevColors, null);
251};
252slider.slide = function(index, direction) {
253    $document.unbind('keyup', app.keyNav);
254    $document.unbind('mousewheel DOMMouseScroll', app.scrollNav);
255    _current = index;
256    _prev = $main.find('.is-active').index();
257    _direction = direction;
258    var $link = $navLinks.eq(_current),
259        $dot = $dots.eq(_current),
260        $project = $projects.eq(_current),
261        $overlay = $overlays.eq(_current),
262        $mask = $masks.eq(_current),
263        $content = $contents.eq(_current);
264    _colors = {
265        bg: $project.data('bg') === undefined ? null : $project.data('bg'),
266        pattern: $project.data('pattern') === undefined ? null : app.hexToRgb($project.data('pattern')),
267        main: $project.data('main') === undefined ? null : app.hexToRgb($project.data('main')),
268        secondary: $project.data('secondary') === undefined ? null : $project.data('secondary'),
269        siteTitle: $project.data('sitetitle') === undefined ? '#fff' : app.hexToRgb($project.data('sitetitle')),
270        btnContact: $project.data('btncontact') === undefined ? '#fff' : $project.data('btncontact'),
271        logo: $project.data('logo') === undefined ? null : $project.data('logo')
272    };
273    slider.updateColors(_colors, _direction);
274
275    var $prevLink = $navLinks.eq(_prev),
276        $prevDot = $dots.eq(_prev),
277        $prevProject = $projects.eq(_prev),
278        $prevOverlay = $overlays.eq(_prev),
279        $prevMask = $masks.eq(_prev),
280        $prevContent = $contents.eq(_prev);
281    if (!$link.data('active')) {
282        $navLinks.removeClass('is-active').data('active', false);
283        $link.addClass('is-active').data('active', true);
284        clearTimeout(myVar);
285        myVar = setTimeout(function() {
286            $link.removeClass('is-active').data('active', false);
287        }, 3000);
288        $projects.removeClass('is-active');
289        $project.addClass('is-active');
290        _dotPos.top = $dot.offset().top;
291        _dotPos.left = $dot.offset().left;
292        _dotPos.bottom = $window.outerHeight() - _dotPos.top - $dot.outerHeight();
293        var dotTween;
294        if (_dotPos.top > $dotClone.offset().top) {
295            dotTween = {
296                bottom: _dotPos.bottom + 'px',
297                ease: Expo.easeIn,
298                onComplete: function() {
299                    TweenLite.to($dotClone, 0.2, {
300                        top: _dotPos.top + 'px',
301                        ease: Expo.easeOut
302                    });
303                }
304            };
305        } else {
306            dotTween = {
307                top: _dotPos.top + 'px',
308                ease: Expo.easeIn,
309                onComplete: function() {
310                    TweenLite.to($dotClone, 0.2, {
311                        bottom: _dotPos.bottom + 'px',
312                        ease: Expo.easeOut
313                    });
314                }
315            };
316        }
317        TweenLite.to($dotClone, 0.4, dotTween);
318        TweenLite.to($prevDot, 0.4, {
319            delay: 0.4,
320            scaleX: 0.65,
321            scaleY: 0.65,
322            ease: Expo.easeOut
323        });
324        TweenLite.to($dot, 0.2, {
325            delay: 0.4,
326            scaleX: 1.5,
327            scaleY: 1.5,
328            ease: Expo.easeOut,
329            onComplete: function() {
330                $document.bind('keyup', app.keyNav);
331                $document.bind('mousewheel DOMMouseScroll', app.scrollNav);
332            }
333        });
334        TweenLite.set($overlay, {
335            y: _direction === 'next' ? '-100%' : '100%'
336        });
337        TweenLite.set($mask, {
338            y: _direction === 'next' ? '-100%' : '100%'
339        });
340        TweenLite.set($overlay.find('.left'), {
341            y: _direction === 'next' ? '100%' : '-100%'
342        });
343        TweenLite.set($mask.find('.left'), {
344            y: _direction === 'next' ? '100%' : '-100%'
345        });
346        TweenLite.set($content, {
347            y: _direction === 'next' ? '100%' : '-100%'
348        });
349        TweenLite.to($prevOverlay, 1, {
350            y: _direction === 'next' ? '100%' : '-100%'
351        });
352        TweenLite.to($prevMask, 1, {
353            y: _direction === 'next' ? '100%' : '-100%'
354        });
355        TweenLite.to($prevOverlay.find('.left'), 1, {
356            y: _direction === 'next' ? '-100%' : '100%'
357        });
358        TweenLite.to($prevMask.find('.left'), 1, {
359            y: _direction === 'next' ? '-100%' : '100%'
360        });
361        TweenLite.to($prevContent, 1, {
362            y: _direction === 'next' ? '-100%' : '100%'
363        });
364        TweenLite.to($overlay, 1, {
365            y: '0%'
366        });
367        TweenLite.to($mask, 1.5, {
368            y: '0%'
369        });
370        TweenLite.to($overlay.find('.left'), 1, {
371            y: '0%'
372        });
373        TweenLite.to($mask.find('.left'), 1.5, {
374            y: '0%'
375        });
376        TweenLite.to($content, 0.75, {
377            y: '0%',
378            onComplete: function() {
379                _prevColors = _colors;
380            }
381        });
382    }
383};
384slider.updateColors = function(colors, direction) {
385    if (direction === null) {
386        $body.css('background', colors.bg);
387        $title.css('color', colors.siteTitle);
388        $btnNext.css('background', colors.bg);
389        $loginLink.css('border-color', colors.btnContact);
390        $loginLink.css('color', colors.btnContact);
391        $localeLink.css('background', colors.btnContact);
392        $dots.css('background', colors.secondary);
393        $dotClone.css('background', colors.secondary);
394        $dotClone.css('border-color', colors.secondary);
395        $navLabel.css('color', colors.secondary);
396    } else {
397        if (!Modernizr.csstransitions) {
398            TweenLite.to($title, 1, {
399                color: colors.siteTitle
400            });
401            TweenLite.to($loginLink, 1, {
402                color: colors.btnContact
403            });
404            TweenLite.to($navLabel, 1, {
405                color: colors.secondary
406            });
407        } else {
408            $title.css('color', colors.siteTitle);
409            $loginLink.css('color', colors.btnContact);
410            $navLabel.css('color', colors.secondary);
411        }
412        TweenLite.to($body, 1, {
413            backgroundColor: colors.bg
414        });
415        TweenLite.to($btnNext, 1, {
416            backgroundColor: colors.bg
417        });
418        TweenLite.to($loginLink, 1, {
419            borderColor: colors.btnContact
420        });
421        TweenLite.to($localeLink, 1, {
422            backgroundColor: colors.btnContact
423        });
424        TweenLite.to($dots, 1, {
425            backgroundColor: colors.secondary
426        });
427        TweenLite.to($dotClone, 1, {
428            backgroundColor: colors.secondary
429        });
430        TweenLite.to($dotClone, 1, {
431            borderColor: colors.secondary
432        });
433    }
434};
435var viewWidth = window.innerWidth / 2,
436    viewHeight = window.innerHeight,
437    xMax = Math.ceil(viewWidth / 140) + 1,
438    yMax = Math.ceil(viewHeight / 140) + 1,
439    group, symbol, groupInView = [],
440    pattern = [];
441
442app.hexToRgb = function(hex) {
443    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
444    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
445        return r + r + g + g + b + b;
446    });
447    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
448    return result ? {
449        r: parseInt(result[1], 16),
450        g: parseInt(result[2], 16),
451        b: parseInt(result[3], 16)
452    } : null;
453};
454
455$login.find('.button').removeClass('button').addClass('login-link');
456$('.LoginIndex dd, .LoginIndex dt').each(function(){
457    $(this).addClass('expand-block');
458});
459$('.LoginIndex dd').last().removeClass('expand-block');
460$login.show(100);
461
462$document.ready(function() {
463    app.init();
464
465    $('.label-lc').click(function(e){
466        e.preventDefault();
467
468        if (!locale) {
469            hideLoginForm();
470            locale = true;
471            $(".SwitchLocale .highlighted").show(800);
472        }
473        else {
474            locale = false;
475            $(".SwitchLocale .highlighted").hide(400);
476        }
477    });
478
479    $('.LoginIndex input').click(function(){
480        $(this).removeClass('invalid');
481    });
482
483    $loginLink.click(function(e){
484        e.preventDefault();
485
486        if (loginformIs) {
487            if ( ($('#login').val().length) && ($('#password').val().length) ) {
488                $login.find('form').submit();
489            }
490            else {
491                $('.LoginIndex input').each(function(){
492                    if (!$(this).val().length) {
493                        $(this).attr('class','class').addClass('invalid');
494                    }
495                });
496            }
497        }
498        else {
499            if (locale)
500            {
501                $(".SwitchLocale .highlighted").hide(400);
502                locale = false;
503            }
504            $(".LoginIndex .expand-block").show(600);
505            $login.addClass("expanded");
506            if ($(document).width() < 481) {
507                $login.addClass("mobile-expanded");
508            }
509            loginformIs = true;
510        }
511
512    });
513
514    $document.keyup(function(e) {
515        if (e.which === 27) {
516            hideLoginForm();
517        }
518    });
519
520    $reglinkMobile.click(function(e){
521        e.preventDefault();
522        regformup = true;
523        $(this).hide();
524        $registration.show(600);
525        $htmlbody.animate({scrollTop: $registrationTitle.offset().top}, 500);
526    });
527
528
529    $document.click(function(){
530        hideLoginForm();
531    });
532
533    $login.click(function(e) {
534        e.stopPropagation();
535    });
536
537});

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.