liushengqiang 1 år sedan
förälder
incheckning
473adc349e

+ 137 - 0
public/book/index.html

@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
+    <script type="text/javascript" src="jquery.min.1.7.js"></script>
+    <script type="text/javascript" src="turn.min.js"></script>
+</head>
+
+<body>
+    <style>
+        body {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: 100vh;
+        }
+
+        #filipbook {
+            margin-top: 20px;
+        }
+
+        .animated {
+            -webkit-transition: margin-left 0.2s ease-in-out;
+            -moz-transition: margin-left 0.2s ease-in-out;
+            -o-transition: margin-left 0.2s ease-in-out;
+            -ms-transition: margin-left 0.2s ease-in-out;
+            transition: margin-left 0.2s ease-in-out;
+        }
+
+        .page {
+            background: white;
+
+            -webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
+            -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
+            -ms-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
+            -o-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
+            box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
+        }
+
+        .shadow {
+            -webkit-transition: -webkit-box-shadow 0.5s;
+            -moz-transition: -moz-box-shadow 0.5s;
+            -o-transition: -webkit-box-shadow 0.5s;
+            -ms-transition: -ms-box-shadow 0.5s;
+            -webkit-box-shadow: 0 0 20px #ccc;
+            -moz-box-shadow: 0 0 20px #ccc;
+            -o-box-shadow: 0 0 20px #ccc;
+            -ms-box-shadow: 0 0 20px #ccc;
+            box-shadow: 0 0 20px #ccc;
+        }
+
+        .even .gradient {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            background-image: url(./pics/right-border.png);
+            background-position: right top;
+            background-repeat: repeat-y;
+        }
+
+        .odd .gradient {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            background-image: url(./pics/left-border.png);
+            background-position: left top;
+            background-repeat: repeat-y;
+        }
+
+        .page-wrapper {
+            -webkit-perspective: 2000px;
+            -moz-perspective: 2000px;
+            -ms-perspective: 2000px;
+            perspective: 2000px;
+        }
+    </style>
+    <div class="contianer">
+        <div id="flipbook" class="animated">
+            <div class="page">
+                <img style="width: 100%; height: 100%; object-fit: cover;"
+                    src="https://gyt.ks3-cn-beijing.ksyuncs.com/1688969499129.png" />
+            </div>
+            <div class="page">
+                <div class="gradient"></div>2
+            </div>
+            <div class="page">
+                <div class="gradient"></div>3
+            </div>
+            <div class="page">
+                <div class="gradient"></div>4
+            </div>
+            <div class="page">
+                <div class="gradient"></div>5
+            </div>
+            <div class="page">
+                <div class="gradient"></div>6
+            </div>
+            <div class="page">
+                <div class="gradient"></div>7
+            </div>
+            <div class="page">
+                <div class="gradient"></div>8
+            </div>
+            <div class="page">
+                <div class="gradient"></div>9
+            </div>
+            <div class="page">
+                <div class="gradient"></div>10
+            </div>
+            <div class="page">
+                <div class="gradient"></div>11
+            </div>
+        </div>
+    </div>
+    <script>
+        $('#flipbook').turn({
+            autoCenter: true,
+            duration: 1000,
+            acceleration: true, // 是否启动硬件加速 如果为触摸设备必须为true
+            pages: 11, // 页码总数
+            elevation: 50, // 转换期间页面的高度
+            width: window.screen.height * .8 * (3 / 4) * 2, // 宽度 单位 px
+            height: window.screen.height * .8, // 高度 单位 px
+            gradients: true, // 是否显示翻页阴影效果
+            // display: 'single', //设置单页还是双页
+        });
+    </script>
+</body>
+
+</html>

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 0
public/book/jquery.min.1.7.js


BIN
public/book/pics/covers.jpg


BIN
public/book/pics/covers.png


BIN
public/book/pics/left-border.png


BIN
public/book/pics/loader.gif


BIN
public/book/pics/preview.jpg


BIN
public/book/pics/right-border.png


BIN
public/book/pics/tab-hover.png


BIN
public/book/pics/tab-off.png


BIN
public/book/pics/tab-on.png


+ 3352 - 0
public/book/turn.js

@@ -0,0 +1,3352 @@
+/**
+ * turn.js 4th release
+ * turnjs.com
+ * turnjs.com/license.txt
+ *
+ * Copyright (C) 2012 Emmanuel Garcia
+ * All rights reserved
+ **/
+
+(function($) {
+
+'use strict';
+
+var has3d,
+  
+  hasRot,
+
+  vendor = '',
+  
+  version = '4.1.0',
+
+  PI = Math.PI,
+
+  A90 = PI/2,
+
+  isTouch = 'ontouchstart' in window,
+
+  mouseEvents = (isTouch) ?
+    {
+      down: 'touchstart',
+      move: 'touchmove',
+      up: 'touchend',
+      over: 'touchstart',
+      out: 'touchend'
+    }
+    :
+    {
+      down: 'mousedown',
+      move: 'mousemove',
+      up: 'mouseup',
+      over: 'mouseover',
+      out: 'mouseout'
+    },
+
+  // Contansts used for each corner
+  //   | tl * tr |
+  // l | *     * | r
+  //   | bl * br |
+
+  corners = {
+    backward: ['bl', 'tl'],
+    forward: ['br', 'tr'],
+    all: ['tl', 'bl', 'tr', 'br', 'l', 'r']
+  },
+
+  // Display values
+
+  displays = ['single', 'double'],
+
+  // Direction values
+
+  directions = ['ltr', 'rtl'],
+
+  // Default options
+
+  turnOptions = {
+
+    // Enables hardware acceleration
+
+    acceleration: true,
+
+    // Display
+
+    display: 'double',
+
+    // Duration of transition in milliseconds
+
+    duration: 600,
+
+    // First page
+
+    page: 1,
+    
+    // Enables gradients
+
+    gradients: true,
+
+    // Corners used when turning the page
+
+    turnCorners: 'bl,br',
+
+    // Events
+
+    when: null
+  },
+
+  flipOptions = {
+
+    // Size of the active zone of each corner
+
+    cornerSize: 100
+
+  },
+
+  // Number of pages in the DOM, minimum value: 6
+
+  pagesInDOM = 6,
+  
+
+turnMethods = {
+
+  // Singleton constructor
+  // $('#selector').turn([options]);
+
+  init: function(options) {
+
+    // Define constants
+    
+    has3d = 'WebKitCSSMatrix' in window || 'MozPerspective' in document.body.style;
+    hasRot = rotationAvailable();
+    vendor = getPrefix();
+
+    var i, that = this, pageNum = 0, data = this.data(), ch = this.children();
+
+    // Set initial configuration
+
+    options = $.extend({
+      width: this.width(),
+      height: this.height(),
+      direction: this.attr('dir') || this.css('direction') || 'ltr'
+    }, turnOptions, options);
+
+    data.opts = options;
+    data.pageObjs = {};
+    data.pages = {};
+    data.pageWrap = {};
+    data.pageZoom = {};
+    data.pagePlace = {};
+    data.pageMv = [];
+    data.zoom = 1;
+    data.totalPages = options.pages || 0;
+    data.eventHandlers = {
+      touchStart: $.proxy(turnMethods._touchStart, this),
+      touchMove: $.proxy(turnMethods._touchMove, this),
+      touchEnd: $.proxy(turnMethods._touchEnd, this),
+      start: $.proxy(turnMethods._eventStart, this)
+    };
+
+
+
+    // Add event listeners
+
+    if (options.when)
+      for (i in options.when)
+        if (has(i, options.when))
+          this.bind(i, options.when[i]);
+
+    // Set the css
+
+    this.css({position: 'relative', width: options.width, height: options.height});
+
+    // Set the initial display
+
+    this.turn('display', options.display);
+
+    // Set the direction
+
+    if (options.direction!=='')
+      this.turn('direction', options.direction);
+    
+    // Prevent blue screen problems of switching to hardware acceleration mode
+    // By forcing hardware acceleration for ever
+
+    if (has3d && !isTouch && options.acceleration)
+      this.transform(translate(0, 0, true));
+
+    // Add pages from the DOM
+
+    for (i = 0; i<ch.length; i++) {
+      if ($(ch[i]).attr('ignore')!='1') {
+        this.turn('addPage', ch[i], ++pageNum);
+      }
+    }
+
+    // Event listeners
+
+    $(this).bind(mouseEvents.down, data.eventHandlers.touchStart).
+      bind('end', turnMethods._eventEnd).
+      bind('pressed', turnMethods._eventPressed).
+      bind('released', turnMethods._eventReleased).
+      bind('flip', turnMethods._flip);
+
+    $(this).parent().bind('start', data.eventHandlers.start);
+
+    $(document).bind(mouseEvents.move, data.eventHandlers.touchMove).
+      bind(mouseEvents.up, data.eventHandlers.touchEnd);
+
+    // Set the initial page
+
+    this.turn('page', options.page);
+
+    // This flipbook is ready
+
+    data.done = true;
+
+    return this;
+  },
+
+  // Adds a page from external data
+
+  addPage: function(element, page) {
+
+    var currentPage,
+      className,
+      incPages = false,
+      data = this.data(),
+      lastPage = data.totalPages+1;
+
+    if (data.destroying)
+      return false;
+
+    // Read the page number from the className of `element` - format: p[0-9]+
+
+    if ((currentPage = /\bp([0-9]+)\b/.exec($(element).attr('class'))))
+      page = parseInt(currentPage[1], 10);
+
+    if (page) {
+      
+      if (page==lastPage)
+        incPages = true;
+      else if (page>lastPage)
+        throw turnError('Page "'+page+'" cannot be inserted');
+
+    } else {
+      
+      page = lastPage;
+      incPages = true;
+
+    }
+
+    if (page>=1 && page<=lastPage) {
+
+      if (data.display=='double')
+        className = (page%2) ? ' odd' : ' even';
+      else
+        className = '';
+
+      // Stop animations
+      if (data.done)
+        this.turn('stop');
+
+      // Move pages if it's necessary
+      if (page in data.pageObjs)
+        turnMethods._movePages.call(this, page, 1);
+
+      // Increase the number of pages
+      if (incPages)
+        data.totalPages = lastPage;
+
+      // Add element
+      data.pageObjs[page] = $(element).
+        css({'float': 'left'}).
+        addClass('page p' + page + className);
+
+      if (!hasHardPage() &&  data.pageObjs[page].hasClass('hard')) {
+        data.pageObjs[page].removeClass('hard');
+      }
+
+      // Add page
+      turnMethods._addPage.call(this, page);
+
+      // Remove pages out of range
+      turnMethods._removeFromDOM.call(this);
+    }
+
+    return this;
+  },
+
+  // Adds a page
+
+  _addPage: function(page) {
+    
+    var data = this.data(),
+      element = data.pageObjs[page];
+
+    if (element)
+      if (turnMethods._necessPage.call(this, page)) {
+
+        if (!data.pageWrap[page]) {
+
+          // Wrapper
+          data.pageWrap[page] = $('<div/>',
+            {'class': 'page-wrapper',
+              page: page,
+              css: {position: 'absolute',
+              overflow: 'hidden'}});
+
+          // Append to this flipbook
+          this.append(data.pageWrap[page]);
+
+          if (!data.pagePlace[page]) {
+            
+            data.pagePlace[page] = page;
+            // Move `pageObjs[page]` to wrapper
+            data.pageObjs[page].appendTo(data.pageWrap[page]);
+          
+         }
+
+          // Set the size of the page
+          var prop = turnMethods._pageSize.call(this, page, true);
+          element.css({width: prop.width, height: prop.height});
+          data.pageWrap[page].css(prop);
+
+        }
+
+        if (data.pagePlace[page] == page) {
+
+         // If the page isn't in another place, create the flip effect
+          turnMethods._makeFlip.call(this, page);
+
+      }
+        
+      } else {
+
+        // Place
+        data.pagePlace[page] = 0;
+
+        // Remove element from the DOM
+        if (data.pageObjs[page])
+          data.pageObjs[page].remove();
+
+      }
+
+  },
+
+  // Checks if a page is in memory
+  
+  hasPage: function(page) {
+
+    return has(page, this.data().pageObjs);
+  
+  },
+
+  // Centers the flipbook
+
+  center: function(page) {
+    
+    var data = this.data(),
+      size = $(this).turn('size'),
+      left = 0;
+
+    if (!data.noCenter) {
+      if (data.display=='double') {
+        var view = this.turn('view', page || data.tpage || data.page);
+
+        if (data.direction=='ltr') {
+          if (!view[0])
+            left -= size.width/4;
+          else if (!view[1])
+            left += size.width/4;
+        } else {
+          if (!view[0])
+            left += size.width/4;
+          else if (!view[1])
+            left -= size.width/4;
+        }
+      
+      }
+
+      $(this).css({marginLeft: left});
+    }
+
+    return this;
+
+  },
+
+  // Destroys the flipbook
+
+  destroy: function () {
+
+    var page,
+      flipbook = this,
+      data = this.data(),
+      events = [
+        'end', 'first', 'flip', 'last', 'pressed',
+        'released', 'start', 'turning', 'turned',
+        'zooming', 'missing'];
+
+    if (trigger('destroying', this)=='prevented')
+      return;
+
+    data.destroying = true;
+
+    $.each(events, function(index, eventName) {
+      flipbook.unbind(eventName);
+    });
+
+    this.parent().unbind('start', data.eventHandlers.start);
+
+    $(document).unbind(mouseEvents.move, data.eventHandlers.touchMove).
+      unbind(mouseEvents.up, data.eventHandlers.touchEnd);
+    
+    while (data.totalPages!==0) {
+      this.turn('removePage', data.totalPages);
+    }
+
+    if (data.fparent)
+      data.fparent.remove();
+
+    if (data.shadow)
+      data.shadow.remove();
+
+    this.removeData();
+    data = null;
+
+    return this;
+
+  },
+
+  // Checks if this element is a flipbook
+
+  is: function() {
+
+    return typeof(this.data().pages)=='object';
+
+  },
+
+  // Sets and gets the zoom value
+
+  zoom: function(newZoom) {
+    
+    var data = this.data();
+
+    if (typeof(newZoom)=='number') {
+
+      if (newZoom<0.001 || newZoom>100)
+        throw turnError(newZoom+ ' is not a value for zoom');
+      
+      if (trigger('zooming', this, [newZoom, data.zoom])=='prevented')
+        return this;
+      
+      var size = this.turn('size'),
+        currentView = this.turn('view'),
+        iz = 1/data.zoom,
+        newWidth = Math.round(size.width * iz * newZoom),
+        newHeight = Math.round(size.height * iz * newZoom);
+    
+      data.zoom = newZoom;
+
+      $(this).turn('stop').
+        turn('size', newWidth, newHeight);
+        /*.
+        css({marginTop: size.height * iz / 2 - newHeight / 2});*/
+
+      if (data.opts.autoCenter)
+        this.turn('center');
+      /*else
+        $(this).css({marginLeft: size.width * iz / 2 - newWidth / 2});*/
+
+      turnMethods._updateShadow.call(this);
+
+      for (var i = 0; i<currentView.length; i++) {
+        if (currentView[i] && data.pageZoom[currentView[i]]!=data.zoom) {
+  
+          this.trigger('zoomed',[
+            currentView[i],
+            currentView,
+            data.pageZoom[currentView[i]],
+            data.zoom]);
+
+          data.pageZoom[currentView[i]] = data.zoom;
+      }
+    }
+
+      return this;
+
+    } else
+      return data.zoom;
+
+  },
+
+  // Gets the size of a page
+
+  _pageSize: function(page, position) {
+
+    var data = this.data(),
+      prop = {};
+
+    if (data.display=='single') {
+
+      prop.width = this.width();
+      prop.height = this.height();
+
+      if (position) {
+        prop.top = 0;
+        prop.left = 0;
+        prop.right = 'auto';
+      }
+
+    } else {
+
+      var pageWidth = this.width()/2,
+        pageHeight = this.height();
+
+      if (data.pageObjs[page].hasClass('own-size')) {
+        prop.width = data.pageObjs[page].width();
+        prop.height = data.pageObjs[page].height();
+      } else {
+        prop.width = pageWidth;
+        prop.height = pageHeight;
+      }
+      
+      if (position) {
+        var odd = page%2;
+        prop.top = (pageHeight-prop.height)/2;
+
+        if (data.direction=='ltr') {
+          
+          prop[(odd) ? 'right' : 'left'] = pageWidth-prop.width;
+          prop[(odd) ? 'left' : 'right'] = 'auto';
+
+        } else {
+          
+          prop[(odd) ? 'left' : 'right'] = pageWidth-prop.width;
+          prop[(odd) ? 'right' : 'left'] = 'auto';
+
+        }
+      
+      }
+    }
+
+    return prop;
+
+  },
+
+  // Prepares the flip effect for a page
+
+  _makeFlip: function(page) {
+
+    var data = this.data();
+
+    if (!data.pages[page] && data.pagePlace[page]==page) {
+      
+      var single = data.display=='single',
+        odd = page%2;
+
+      data.pages[page] = data.pageObjs[page].
+        css(turnMethods._pageSize.call(this, page)).
+        flip({
+          page: page,
+          next: (odd || single) ? page+1 : page-1,
+          turn: this
+        }).
+        flip('disable', data.disabled);
+
+        // Issue about z-index
+        turnMethods._setPageLoc.call(this, page);
+
+        data.pageZoom[page] = data.zoom;
+        
+    }
+
+    return data.pages[page];
+  },
+
+  // Makes pages within a range
+
+  _makeRange: function() {
+
+    var page, range,
+      data = this.data();
+
+    if (data.totalPages<1)
+      return;
+
+    range = this.turn('range');
+
+    for (page = range[0]; page<=range[1]; page++)
+      turnMethods._addPage.call(this, page);
+
+  },
+
+  // Returns a range of pages that should be in the DOM
+  // Example:
+  // - page in the current view, return true
+  // * page is in the range, return true
+  // Otherwise, return false
+  //
+  // 1 2-3 4-5 6-7 8-9 10-11 12-13
+  //   **  **  --   **  **
+
+  range: function(page) {
+
+    var remainingPages, left, right, view,
+      data = this.data();
+
+      page = page || data.tpage || data.page || 1;
+      view = turnMethods._view.call(this, page);
+
+      if (page<1 || page>data.totalPages)
+        throw turnError('"'+page+'" is not a valid page');
+
+    
+      view[1] = view[1] || view[0];
+      
+      if (view[0]>=1 && view[1]<=data.totalPages) {
+
+        remainingPages = Math.floor((pagesInDOM-2)/2);
+
+        if (data.totalPages-view[1] > view[0]) {
+          left = Math.min(view[0]-1, remainingPages);
+          right = 2*remainingPages-left;
+        } else {
+          right = Math.min(data.totalPages-view[1], remainingPages);
+          left = 2*remainingPages-right;
+        }
+
+      } else {
+        left = pagesInDOM-1;
+        right = pagesInDOM-1;
+      }
+
+      return [Math.max(1, view[0]-left),
+          Math.min(data.totalPages, view[1]+right)];
+
+  },
+
+  // Detects if a page is within the range of `pagesInDOM` from the current view
+
+  _necessPage: function(page) {
+    
+    if (page===0)
+      return true;
+
+    var range = this.turn('range');
+
+    return this.data().pageObjs[page].hasClass('fixed') ||
+      (page>=range[0] && page<=range[1]);
+    
+  },
+
+  // Releases memory by removing pages from the DOM
+
+  _removeFromDOM: function() {
+
+    var page, data = this.data();
+
+    for (page in data.pageWrap)
+      if (has(page, data.pageWrap) &&
+        !turnMethods._necessPage.call(this, page))
+      turnMethods._removePageFromDOM.call(this, page);
+    
+  },
+
+  // Removes a page from DOM and its internal references
+
+  _removePageFromDOM: function(page) {
+
+    var data = this.data();
+
+    if (data.pages[page]) {
+      var dd = data.pages[page].data();
+
+      flipMethods._moveFoldingPage.call(data.pages[page], false);
+
+      if (dd.f && dd.f.fwrapper)
+        dd.f.fwrapper.remove();
+
+      data.pages[page].removeData();
+      data.pages[page].remove();
+      delete data.pages[page];
+    }
+
+    if (data.pageObjs[page])
+      data.pageObjs[page].remove();
+
+    if (data.pageWrap[page]) {
+      data.pageWrap[page].remove();
+      delete data.pageWrap[page];
+    }
+
+    turnMethods._removeMv.call(this, page);
+
+    delete data.pagePlace[page];
+    delete data.pageZoom[page];
+
+  },
+
+  // Removes a page
+
+  removePage: function(page) {
+
+    var data = this.data();
+
+    // Delete all the pages
+    if (page=='*') {
+      
+      while (data.totalPages!==0) {
+        this.turn('removePage', data.totalPages);
+      }
+
+    } else {
+
+      if (page<1 || page>data.totalPages)
+        throw turnError('The page '+ page + ' doesn\'t exist');
+        
+      if (data.pageObjs[page]) {
+
+        // Stop animations
+        this.turn('stop');
+
+        // Remove `page`
+        turnMethods._removePageFromDOM.call(this, page);
+
+        delete data.pageObjs[page];
+
+      }
+
+      // Move the pages
+      turnMethods._movePages.call(this, page, -1);
+
+      // Resize the size of this flipbook
+      data.totalPages = data.totalPages-1;
+
+      // Check the current view
+
+      if (data.page>data.totalPages) {
+
+       data.page = null;
+       turnMethods._fitPage.call(this, data.totalPages);
+
+      } else {
+
+        turnMethods._makeRange.call(this);
+        this.turn('update');
+
+      }
+    }
+
+    return this;
+  
+  },
+
+  // Moves pages
+
+  _movePages: function(from, change) {
+
+    var page,
+      that = this,
+      data = this.data(),
+      single = data.display=='single',
+      move = function(page) {
+
+        var next = page + change,
+          odd = next%2,
+          className = (odd) ? ' odd ' : ' even ';
+
+        if (data.pageObjs[page])
+          data.pageObjs[next] = data.pageObjs[page].
+            removeClass('p' + page + ' odd even').
+            addClass('p' + next + className);
+
+        if (data.pagePlace[page] && data.pageWrap[page]) {
+
+          data.pagePlace[next] = next;
+        
+          if (data.pageObjs[next].hasClass('fixed'))
+            data.pageWrap[next] = data.pageWrap[page].
+              attr('page', next);
+          else
+            data.pageWrap[next] = data.pageWrap[page].
+              css(turnMethods._pageSize.call(that, next, true)).
+              attr('page', next);
+      
+            if (data.pages[page])
+              data.pages[next] = data.pages[page].
+                flip('options', {
+                  page: next,
+                  next: (single || odd) ? next+1 : next-1
+                });
+
+            if (change) {
+              delete data.pages[page];
+              delete data.pagePlace[page];
+              delete data.pageZoom[page];
+              delete data.pageObjs[page];
+              delete data.pageWrap[page];
+            }
+
+        }
+
+    };
+
+    if (change>0)
+      for (page=data.totalPages; page>=from; page--)
+        move(page);
+    else
+      for (page=from; page<=data.totalPages; page++)
+        move(page);
+
+  },
+
+  // Sets or Gets the display mode
+
+  display: function(display) {
+
+    var data = this.data(),
+      currentDisplay = data.display;
+
+    if (display===undefined) {
+      
+      return currentDisplay;
+
+    } else {
+
+      if ($.inArray(display, displays)==-1)
+        throw turnError('"'+display + '" is not a value for display');
+      
+      switch(display) {
+        case 'single':
+
+          // Create a temporal page to use as folded page
+
+          if (!data.pageObjs[0]) {
+            this.turn('stop').
+              css({'overflow': 'hidden'});
+
+            data.pageObjs[0] = $('<div />',
+                {'class': 'page p-temporal'}).
+              css({width: this.width(), height: this.height()}).
+              appendTo(this);
+          }
+
+          this.addClass('shadow');
+
+        break;
+        case 'double':
+
+          // Remove the temporal page
+
+          if (data.pageObjs[0]) {
+            this.turn('stop').css({'overflow': ''});
+            data.pageObjs[0].remove();
+            delete data.pageObjs[0];
+          }
+
+          this.removeClass('shadow');
+
+        break;
+      }
+      
+
+      data.display = display;
+
+      if (currentDisplay) {
+        var size = this.turn('size');
+        turnMethods._movePages.call(this, 1, 0);
+        this.turn('size', size.width, size.height).
+          turn('update');
+      }
+
+      return this;
+
+    }
+  
+  },
+  
+  // Gets and sets the direction of the flipbook
+
+  direction: function(dir) {
+
+    var data = this.data();
+
+    if (dir===undefined) {
+
+      return data.direction;
+
+    } else {
+
+      dir = dir.toLowerCase();
+
+      if ($.inArray(dir, directions)==-1)
+        throw turnError('"' + dir + '" is not a value for direction');
+
+      if (dir=='rtl') {
+        $(this).attr('dir', 'ltr').
+          css({direction: 'ltr'});
+      }
+
+      data.direction = dir;
+
+      if (data.done)
+        this.turn('size', $(this).width(), $(this).height());
+
+      return this;
+    }
+
+  },
+
+  // Detects animation
+
+  animating: function() {
+
+    return this.data().pageMv.length>0;
+
+  },
+
+  // Gets the current activated corner
+
+  corner: function() {
+    
+    var corner,
+      page,
+      data = this.data();
+
+    for (page in data.pages) {
+      if (has(page, data.pages))
+        if ((corner = data.pages[page].flip('corner'))) {
+          return corner;
+        }
+    }
+
+    return false;
+  },
+
+  // Gets the data stored in the flipbook
+
+  data: function() {
+    
+    return this.data();
+
+  },
+
+  // Disables and enables the effect
+
+  disable: function(disable) {
+
+    var page,
+      data = this.data(),
+      view = this.turn('view');
+
+    data.disabled = disable===undefined || disable===true;
+
+    for (page in data.pages) {
+      if (has(page, data.pages))
+        data.pages[page].flip('disable',
+          (data.disabled) ? true : $.inArray(parseInt(page, 10), view)==-1);
+    }
+
+    return this;
+
+  },
+
+  // Disables and enables the effect
+
+  disabled: function(disable) {
+
+    if (disable===undefined) {
+      return this.data().disabled===true;
+    } else {
+      return this.turn('disable', disable);
+    }
+
+  },
+
+  // Gets and sets the size
+
+  size: function(width, height) {
+
+    if (width===undefined || height===undefined) {
+      
+      return {width: this.width(), height: this.height()};
+
+    } else {
+
+      this.turn('stop');
+
+      var page, prop,
+        data = this.data(),
+        pageWidth = (data.display=='double') ? width/2 : width;
+
+      this.css({width: width, height: height});
+
+      if (data.pageObjs[0])
+        data.pageObjs[0].css({width: pageWidth, height: height});
+      
+      for (page in data.pageWrap) {
+        if (!has(page, data.pageWrap)) continue;
+
+        prop = turnMethods._pageSize.call(this, page, true);
+
+        data.pageObjs[page].css({width: prop.width, height: prop.height});
+        data.pageWrap[page].css(prop);
+        
+        if (data.pages[page])
+          data.pages[page].css({width: prop.width, height: prop.height});
+      }
+
+      this.turn('resize');
+
+      return this;
+
+    }
+  },
+
+  // Resizes each page
+
+  resize: function() {
+
+    var page, data = this.data();
+
+    if (data.pages[0]) {
+      data.pageWrap[0].css({left: -this.width()});
+      data.pages[0].flip('resize', true);
+    }
+
+    for (page = 1; page <= data.totalPages; page++)
+      if (data.pages[page])
+        data.pages[page].flip('resize', true);
+
+    turnMethods._updateShadow.call(this);
+
+    if (data.opts.autoCenter)
+      this.turn('center');
+
+  },
+
+  // Removes an animation from the cache
+
+  _removeMv: function(page) {
+
+    var i, data = this.data();
+      
+    for (i=0; i<data.pageMv.length; i++)
+      if (data.pageMv[i]==page) {
+        data.pageMv.splice(i, 1);
+        return true;
+      }
+
+    return false;
+
+  },
+
+  // Adds an animation to the cache
+  
+  _addMv: function(page) {
+
+    var data = this.data();
+
+    turnMethods._removeMv.call(this, page);
+    data.pageMv.push(page);
+
+  },
+
+  // Gets indexes for a view
+
+  _view: function(page) {
+  
+    var data = this.data();
+    
+    page = page || data.page;
+
+    if (data.display=='double')
+      return (page%2) ? [page-1, page] : [page, page+1];
+    else
+      return [page];
+
+  },
+
+  // Gets a view
+
+  view: function(page) {
+
+    var data = this.data(),
+      view = turnMethods._view.call(this, page);
+
+    if (data.display=='double')
+      return [(view[0]>0) ? view[0] : 0,
+        (view[1]<=data.totalPages) ? view[1] : 0];
+    else
+      return [(view[0]>0 && view[0]<=data.totalPages) ? view[0] : 0];
+
+  },
+
+  // Stops animations
+
+  stop: function(ignore, animate) {
+
+    if (this.turn('animating')) {
+  
+      var i, opts, page,
+        data = this.data();
+
+      if (data.tpage) {
+        data.page = data.tpage;
+        delete data['tpage'];
+      }
+
+      for (i = 0; i<data.pageMv.length; i++) {
+
+        if (!data.pageMv[i] || data.pageMv[i]===ignore)
+          continue;
+
+        page = data.pages[data.pageMv[i]];
+        opts = page.data().f.opts;
+
+        page.flip('hideFoldedPage', animate);
+
+        if (!animate)
+          flipMethods._moveFoldingPage.call(page, false);
+
+        if (opts.force) {
+          opts.next = (opts.page%2===0) ? opts.page-1 : opts.page+1;
+          delete opts['force'];
+        }
+
+      }
+    }
+    
+    this.turn('update');
+
+    return this;
+  },
+
+  // Gets and sets the number of pages
+
+  pages: function(pages) {
+
+    var data = this.data();
+
+    if (pages) {
+
+      if (pages<data.totalPages) {
+
+        for (var page = data.totalPages; page>pages; page--)
+          this.turn('removePage', page);
+
+      }
+
+        data.totalPages = pages;
+        turnMethods._fitPage.call(this, data.page);
+
+      return this;
+
+    } else
+      return data.totalPages;
+
+  },
+
+  // Checks missing pages
+
+  _missing : function(page) {
+    
+    var data = this.data();
+
+    if (data.totalPages<1)
+      return;
+
+    var p,
+        range = this.turn('range', page),
+        missing = [];
+
+    for (p = range[0]; p<=range[1]; p++) {
+      if (!data.pageObjs[p])
+        missing.push(p);
+    }
+
+    if (missing.length>0)
+      this.trigger('missing', [missing]);
+
+  },
+
+  // Sets a page without effect
+
+  _fitPage: function(page) {
+
+    var data = this.data(),
+      newView = this.turn('view', page);
+
+    turnMethods._missing.call(this, page);
+    
+    if (!data.pageObjs[page])
+      return;
+
+    data.page = page;
+  
+    this.turn('stop');
+
+    for (var i = 0; i<newView.length; i++) {
+
+      if (newView[i] && data.pageZoom[newView[i]]!=data.zoom) {
+  
+        this.trigger('zoomed',[
+          newView[i],
+          newView,
+          data.pageZoom[newView[i]],
+          data.zoom]);
+
+        data.pageZoom[newView[i]] = data.zoom;
+
+      }
+    }
+
+    turnMethods._removeFromDOM.call(this);
+    turnMethods._makeRange.call(this);
+    turnMethods._updateShadow.call(this);
+    this.trigger('turned', [page, newView]);
+    this.turn('update');
+
+    if (data.opts.autoCenter)
+      this.turn('center');
+
+  },
+  
+  // Turns the page
+
+  _turnPage: function(page) {
+
+    var current,
+      next,
+      data = this.data(),
+      place = data.pagePlace[page],
+      view = this.turn('view'),
+      newView = this.turn('view', page);
+
+
+    if (data.page!=page) {
+
+      var currentPage = data.page;
+
+      if (trigger('turning', this, [page, newView])=='prevented') {
+
+        if (currentPage==data.page && $.inArray(place, data.pageMv)!=-1)
+          data.pages[place].flip('hideFoldedPage', true);
+        
+        return;
+
+      }
+
+      if ($.inArray(1, newView)!=-1)
+        this.trigger('first');
+      if ($.inArray(data.totalPages, newView)!=-1)
+        this.trigger('last');
+
+    }
+
+    if (data.display=='single') {
+      current = view[0];
+      next = newView[0];
+    } else if (view[1] && page>view[1]) {
+      current = view[1];
+      next = newView[0];
+    } else if (view[0] && page<view[0]) {
+      current = view[0];
+      next = newView[1];
+    }
+
+    var optsCorners = data.opts.turnCorners.split(','),
+      flipData = data.pages[current].data().f,
+      opts = flipData.opts,
+      actualPoint = flipData.point;
+
+    turnMethods._missing.call(this, page);
+    
+    if (!data.pageObjs[page])
+      return;
+
+    this.turn('stop');
+
+    data.page = page;
+
+    turnMethods._makeRange.call(this);
+
+    data.tpage = next;
+
+    if (opts.next!=next) {
+      opts.next = next;
+      opts.force = true;
+    }
+
+    this.turn('update');
+
+    flipData.point = actualPoint;
+    
+    if (flipData.effect=='hard')
+      if (data.direction=='ltr')
+        data.pages[current].flip('turnPage',
+          (page>current) ? 'r' : 'l');
+      else
+        data.pages[current].flip('turnPage',
+          (page>current) ? 'l' : 'r');
+    else {
+      if (data.direction=='ltr')
+        data.pages[current].flip('turnPage',
+          optsCorners[(page>current) ? 1 : 0]);
+      else
+        data.pages[current].flip('turnPage',
+          optsCorners[(page>current) ? 0 : 1]);
+    }
+
+  },
+
+  // Gets and sets a page
+
+  page: function(page) {
+
+    var data = this.data();
+
+    if (page===undefined) {
+      
+      return data.page;
+
+    } else {
+
+      if (!data.disabled && !data.destroying) {
+
+        page = parseInt(page, 10);
+
+        if (page>0 && page<=data.totalPages) {
+
+          if (page!=data.page) {
+            if (!data.done || $.inArray(page, this.turn('view'))!=-1)
+              turnMethods._fitPage.call(this, page);
+            else
+              turnMethods._turnPage.call(this, page);
+          }
+      
+          return this;
+
+        } else {
+        
+          throw turnError('The page ' + page + ' does not exist');
+
+        }
+
+      }
+
+    }
+
+  },
+
+  // Turns to the next view
+
+  next: function() {
+
+    return this.turn('page', Math.min(this.data().totalPages,
+      turnMethods._view.call(this, this.data().page).pop() + 1));
+  
+  },
+
+  // Turns to the previous view
+
+  previous: function() {
+
+    return this.turn('page', Math.max(1,
+      turnMethods._view.call(this, this.data().page).shift() - 1));
+
+  },
+
+  // Shows a peeling corner
+
+  peel: function(corner, animate) {
+    
+    var data = this.data(),
+      view = this.turn('view');
+
+    animate = (animate===undefined) ? true : animate===true;
+
+    if (corner===false) {
+      
+      this.turn('stop', null, animate);
+
+    } else {
+    
+      if (data.display=='single') {
+
+        data.pages[data.page].flip('peel', corner, animate);
+
+      } else {
+
+        var page;
+
+        if (data.direction=='ltr') {
+          
+          page = (corner.indexOf('l')!=-1) ? view[0] : view[1];
+
+        } else {
+          
+          page = (corner.indexOf('l')!=-1) ? view[1] : view[0];
+
+        }
+        
+        if (data.pages[page])
+          data.pages[page].flip('peel', corner, animate);
+
+      }
+    }
+
+    return this;
+
+  },
+
+  // Adds a motion to the internal list
+  // This event is called in context of flip
+
+  _addMotionPage: function() {
+
+    var opts = $(this).data().f.opts,
+      turn = opts.turn,
+      dd = turn.data();
+
+    turnMethods._addMv.call(turn, opts.page);
+
+  },
+
+  // This event is called in context of flip
+
+  _eventStart: function(e, opts, corner) {
+
+    var data = opts.turn.data(),
+      actualZoom = data.pageZoom[opts.page];
+
+    if (e.isDefaultPrevented()) {
+      turnMethods._updateShadow.call(opts.turn);
+      return;
+    }
+
+    if (actualZoom && actualZoom!=data.zoom) {
+      
+      opts.turn.trigger('zoomed',[
+        opts.page,
+        opts.turn.turn('view', opts.page),
+        actualZoom,
+        data.zoom]);
+
+      data.pageZoom[opts.page] = data.zoom;
+
+    }
+
+    if (data.display=='single' && corner) {
+
+      if ((corner.charAt(1)=='l' && data.direction=='ltr') ||
+        (corner.charAt(1)=='r' && data.direction=='rtl'))
+      {
+        
+        opts.next = (opts.next<opts.page) ? opts.next : opts.page-1;
+        opts.force = true;
+
+      } else {
+        
+        opts.next = (opts.next>opts.page) ? opts.next : opts.page+1;
+
+      }
+
+    }
+
+    turnMethods._addMotionPage.call(e.target);
+    turnMethods._updateShadow.call(opts.turn);
+  },
+
+  // This event is called in context of flip
+
+  _eventEnd: function(e, opts, turned) {
+  
+    var that = $(e.target),
+      data = that.data().f,
+      turn = opts.turn,
+      dd = turn.data();
+
+    if (turned) {
+
+      var tpage = dd.tpage || dd.page;
+    
+      if (tpage==opts.next || tpage==opts.page) {
+        delete dd.tpage;
+
+        turnMethods._fitPage.call(turn, tpage || opts.next, true);
+      }
+
+    } else {
+      
+      turnMethods._removeMv.call(turn, opts.page);
+      turnMethods._updateShadow.call(turn);
+      turn.turn('update');
+
+    }
+    
+  },
+  
+  // This event is called in context of flip
+
+  _eventPressed: function(e) {
+
+    var page,
+      data = $(e.target).data().f,
+      turn = data.opts.turn,
+      turnData = turn.data(),
+      pages = turnData.pages;
+    
+    turnData.mouseAction = true;
+
+    turn.turn('update');
+
+    return data.time = new Date().getTime();
+
+  },
+
+  // This event is called in context of flip
+
+  _eventReleased: function(e, point) {
+
+    var outArea,
+      page = $(e.target),
+      data = page.data().f,
+      turn = data.opts.turn,
+      turnData = turn.data();
+    
+    if (turnData.display=='single') {
+      outArea = (point.corner=='br' || point.corner=='tr') ?
+        point.x<page.width()/2:
+        point.x>page.width()/2;
+    } else {
+      outArea = point.x<0 || point.x>page.width();
+    }
+
+    if ((new Date()).getTime()-data.time<200 || outArea) {
+
+      e.preventDefault();
+      turnMethods._turnPage.call(turn, data.opts.next);
+
+    }
+
+    turnData.mouseAction = false;
+
+  },
+
+  // This event is called in context of flip
+  
+  _flip: function(e) {
+
+    e.stopPropagation();
+
+    var opts = $(e.target).data().f.opts;
+
+    opts.turn.trigger('turn', [opts.next]);
+
+    if (opts.turn.data().opts.autoCenter) {
+      opts.turn.turn('center', opts.next);
+    }
+
+  },
+
+ //
+  _touchStart: function() {
+    var data = this.data();
+    for (var page in data.pages) {
+      if (has(page, data.pages) &&
+        flipMethods._eventStart.apply(data.pages[page], arguments)===false) {
+          return false;
+      }
+    }
+  },
+  
+  //
+  _touchMove: function() {
+    var data = this.data();
+    for (var page in data.pages) {
+      if (has(page, data.pages)) {
+        flipMethods._eventMove.apply(data.pages[page], arguments);
+      }
+    }
+  },
+
+  //
+  _touchEnd: function() {
+    var data = this.data();
+    for (var page in data.pages) {
+      if (has(page, data.pages)) {
+        flipMethods._eventEnd.apply(data.pages[page], arguments);
+      }
+    }
+  },
+
+  // Calculate the z-index value for pages during the animation
+
+  calculateZ: function(mv) {
+
+    var i, page, nextPage, placePage, dpage,
+      that = this,
+      data = this.data(),
+      view = this.turn('view'),
+      currentPage = view[0] || view[1],
+      total = mv.length-1,
+      r = {pageZ: {}, partZ: {}, pageV: {}},
+
+      addView = function(page) {
+        var view = that.turn('view', page);
+        if (view[0]) r.pageV[view[0]] = true;
+        if (view[1]) r.pageV[view[1]] = true;
+      };
+    
+    for (i = 0; i<=total; i++) {
+      page = mv[i];
+      nextPage = data.pages[page].data().f.opts.next;
+      placePage = data.pagePlace[page];
+      addView(page);
+      addView(nextPage);
+      dpage = (data.pagePlace[nextPage]==nextPage) ? nextPage : page;
+      r.pageZ[dpage] = data.totalPages - Math.abs(currentPage-dpage);
+      r.partZ[placePage] = data.totalPages*2 -  total + i;
+    }
+
+    return r;
+  },
+
+  // Updates the z-index and display property of every page
+
+  update: function() {
+
+    var page,
+      data = this.data();
+
+    if (this.turn('animating') && data.pageMv[0]!==0) {
+
+      // Update motion
+
+      var p, apage, fixed,
+        pos = this.turn('calculateZ', data.pageMv),
+        corner = this.turn('corner'),
+        actualView = this.turn('view'),
+        newView = this.turn('view', data.tpage);
+  
+      for (page in data.pageWrap) {
+
+        if (!has(page, data.pageWrap))
+          continue;
+
+        fixed = data.pageObjs[page].hasClass('fixed');
+
+        data.pageWrap[page].css({
+          display: (pos.pageV[page] || fixed) ? '' : 'none',
+          zIndex:
+            (data.pageObjs[page].hasClass('hard') ?
+              pos.partZ[page]
+              :
+              pos.pageZ[page]
+            ) || (fixed ? -1 : 0)
+        });
+
+        if ((p = data.pages[page])) {
+
+          p.flip('z', pos.partZ[page] || null);
+
+          if (pos.pageV[page])
+            p.flip('resize');
+          
+          if (data.tpage) { // Is it turning the page to `tpage`?
+
+            p.flip('hover', false).
+              flip('disable',
+                $.inArray(parseInt(page, 10), data.pageMv)==-1 &&
+                page!=newView[0] &&
+                page!=newView[1]);
+
+          } else {
+
+            p.flip('hover', corner===false).
+              flip('disable', page!=actualView[0] && page!=actualView[1]);
+
+          }
+
+        }
+
+      }
+
+    } else {
+
+      // Update static pages
+
+      for (page in data.pageWrap) {
+
+        if (!has(page, data.pageWrap))
+          continue;
+
+        var pageLocation = turnMethods._setPageLoc.call(this, page);
+
+        if (data.pages[page]) {
+          data.pages[page].
+            flip('disable', data.disabled || pageLocation!=1).
+            flip('hover', true).
+            flip('z', null);
+        }
+      }
+    }
+
+    return this;
+  },
+
+  // Updates the position and size of the flipbook's shadow
+
+  _updateShadow: function() {
+    
+    var view, view2, shadow,
+      data = this.data(),
+      width = this.width(),
+      height = this.height(),
+      pageWidth = (data.display=='single') ? width : width/2;
+
+    view = this.turn('view');
+
+    if (!data.shadow) {
+      data.shadow = $('<div />', {
+          'class': 'shadow',
+          'css': divAtt(0, 0, 0).css
+        }).
+        appendTo(this);
+    }
+
+    for (var i = 0; i<data.pageMv.length; i++) {
+      if (!view[0] || !view[1])
+        break;
+    
+      view = this.turn('view', data.pages[data.pageMv[i]].data().f.opts.next);
+      view2 = this.turn('view', data.pageMv[i]);
+
+      view[0] = view[0] && view2[0];
+      view[1] = view[1] && view2[1];
+    }
+
+    if (!view[0]) shadow = (data.direction=='ltr') ? 1 : 2;
+    else if (!view[1]) shadow = (data.direction=='ltr') ? 2 : 1;
+    else shadow = 3;
+
+    switch (shadow) {
+      case 1:
+        data.shadow.css({
+          width: pageWidth,
+          height: height,
+          top: 0,
+          left: pageWidth
+        });
+        break;
+      case 2:
+        data.shadow.css({
+          width: pageWidth,
+          height: height,
+          top: 0,
+          left: 0
+        });
+        break;
+      case 3:
+        data.shadow.css({
+          width: width,
+          height: height,
+          top: 0,
+          left: 0
+        });
+        break;
+    }
+
+  },
+
+  // Sets the z-index and display property of a page
+  // It depends on the current view
+
+  _setPageLoc: function(page) {
+
+    var data = this.data(),
+      view = this.turn('view'),
+      loc = 0;
+
+    
+    if (page==view[0] || page==view[1])
+      loc = 1;
+    else if (
+      (data.display=='single' && page==view[0]+1) ||
+      (data.display=='double' && page==view[0]-2 || page==view[1]+2)
+    )
+      loc = 2;
+
+    if (!this.turn('animating'))
+      switch (loc) {
+        case 1:
+          data.pageWrap[page].css(
+          {
+            zIndex: data.totalPages,
+            display: ''
+          });
+        break;
+        case 2:
+          data.pageWrap[page].css(
+          {
+            zIndex: data.totalPages-1,
+            display: ''
+          });
+        break;
+        case 0:
+          data.pageWrap[page].css(
+          {
+            zIndex: 0,
+            display: (data.pageObjs[page].hasClass('fixed')) ? '' : 'none'}
+          );
+        break;
+      }
+    
+    return loc;
+  },
+
+  // Gets and sets the options
+
+  options: function(options) {
+    
+    if (options===undefined) {
+      
+      return this.data().opts;
+
+    } else {
+
+      var data = this.data();
+
+      // Set new values
+
+      $.extend(data.opts, options);
+      
+      // Set pages
+
+      if (options.pages)
+        this.turn('pages', options.pages);
+
+      // Set page
+
+      if (options.page)
+        this.turn('page', options.page);
+
+      // Set display
+
+      if (options.display)
+        this.turn('display', options.display);
+      
+      // Set direction
+
+      if (options.direction)
+        this.turn('direction', options.direction);
+
+      // Set size
+
+      if (options.width && options.height)
+        this.turn('size', options.width, options.height);
+      
+      // Add event listeners
+
+      if (options.when)
+        for (var eventName in options.when)
+          if (has(eventName, options.when)) {
+            this.unbind(eventName).
+              bind(eventName, options.when[eventName]);
+          }
+
+      return this;
+    }
+
+  },
+
+  // Gets the current version
+
+  version: function() {
+
+    return version;
+
+  }
+},
+
+// Methods and properties for the flip page effect
+
+flipMethods = {
+
+  // Constructor
+
+  init: function(opts) {
+
+    this.data({f: {
+      disabled: false,
+      hover: false,
+      effect: (this.hasClass('hard')) ? 'hard' : 'sheet'
+    }});
+  
+    this.flip('options', opts);
+
+    flipMethods._addPageWrapper.call(this);
+
+    return this;
+  },
+
+  setData: function(d) {
+    
+    var data = this.data();
+
+    data.f = $.extend(data.f, d);
+
+    return this;
+  },
+
+  options: function(opts) {
+    
+    var data = this.data().f;
+
+    if (opts) {
+      flipMethods.setData.call(this,
+        {opts: $.extend({}, data.opts || flipOptions, opts)});
+      return this;
+    } else
+      return data.opts;
+
+  },
+
+  z: function(z) {
+    
+    var data = this.data().f;
+
+    data.opts['z-index'] = z;
+
+    if (data.fwrapper)
+      data.fwrapper.css({
+        zIndex: z || parseInt(data.parent.css('z-index'), 10) || 0
+      });
+
+    return this;
+  },
+
+  _cAllowed: function() {
+    
+    var data = this.data().f,
+      page = data.opts.page,
+      turnData = data.opts.turn.data(),
+      odd = page%2;
+    
+    if (data.effect=='hard') {
+    
+      return (turnData.direction=='ltr') ?
+        [(odd) ? 'r' : 'l'] :
+        [(odd) ? 'l' : 'r'];
+
+    } else {
+
+      if (turnData.display=='single') {
+
+        if (page==1)
+          return (turnData.direction=='ltr') ?
+            corners['forward'] : corners['backward'];
+        else if (page==turnData.totalPages)
+          return (turnData.direction=='ltr') ?
+            corners['backward'] : corners['forward'];
+        else
+          return corners['all'];
+
+      } else {
+
+        return (turnData.direction=='ltr') ?
+          corners[(odd) ? 'forward' : 'backward']
+          :
+          corners[(odd) ? 'backward' : 'forward'];
+
+      }
+
+    }
+
+  },
+
+  _cornerActivated: function(p) {
+
+    var data = this.data().f,
+      width = this.width(),
+      height = this.height(),
+      point = {x: p.x, y: p.y, corner: ''},
+      csz = data.opts.cornerSize;
+
+    if (point.x<=0 || point.y<=0 || point.x>=width || point.y>=height)
+      return false;
+
+    var allowedCorners = flipMethods._cAllowed.call(this);
+
+    switch (data.effect) {
+      case 'hard':
+        
+        if (point.x>width-csz)
+          point.corner = 'r';
+        else if (point.x<csz)
+          point.corner = 'l';
+        else
+          return false;
+            
+        break;
+
+      case 'sheet':
+        
+        if (point.y<csz)
+          point.corner+= 't';
+        else if (point.y>=height-csz)
+          point.corner+= 'b';
+        else
+          return false;
+    
+        if (point.x<=csz)
+          point.corner+= 'l';
+        else if (point.x>=width-csz)
+          point.corner+= 'r';
+        else
+          return false;
+     
+        break;
+      }
+
+    return (!point.corner || $.inArray(point.corner, allowedCorners)==-1) ?
+      false : point;
+
+  },
+
+  _isIArea: function(e) {
+
+    var pos = this.data().f.parent.offset();
+
+    e = (isTouch && e.originalEvent) ? e.originalEvent.touches[0] : e;
+
+    return flipMethods._cornerActivated.call(this,
+      {
+        x: e.pageX-pos.left,
+        y: e.pageY-pos.top
+      });
+
+  },
+
+  _c: function(corner, opts) {
+
+    opts = opts || 0;
+
+    switch (corner) {
+      case 'tl':
+        return point2D(opts, opts);
+      case 'tr':
+        return point2D(this.width()-opts, opts);
+      case 'bl':
+        return point2D(opts, this.height()-opts);
+      case 'br':
+        return point2D(this.width()-opts, this.height()-opts);
+      case 'l':
+        return point2D(opts, 0);
+      case 'r':
+        return point2D(this.width()-opts, 0);
+    }
+
+  },
+
+  _c2: function(corner) {
+
+    switch (corner) {
+      case 'tl':
+        return point2D(this.width()*2, 0);
+      case 'tr':
+        return point2D(-this.width(), 0);
+      case 'bl':
+        return point2D(this.width()*2, this.height());
+      case 'br':
+        return point2D(-this.width(), this.height());
+      case 'l':
+        return point2D(this.width()*2, 0);
+      case 'r':
+        return point2D(-this.width(), 0);
+    }
+
+  },
+
+  _foldingPage: function() {
+
+    var data = this.data().f;
+
+    if (!data)
+      return;
+
+    var opts = data.opts;
+
+    if (opts.turn) {
+      data = opts.turn.data();
+      if (data.display == 'single')
+        return (opts.next>1 || opts.page>1) ? data.pageObjs[0] : null;
+      else
+        return data.pageObjs[opts.next];
+    }
+
+  },
+
+  _backGradient: function() {
+
+    var data = this.data().f,
+      turnData = data.opts.turn.data(),
+      gradient =  turnData.opts.gradients && (turnData.display=='single' ||
+         (data.opts.page!=2 && data.opts.page!=turnData.totalPages-1));
+
+    if (gradient && !data.bshadow)
+      data.bshadow = $('<div/>', divAtt(0, 0, 1)).
+        css({'position': '', width: this.width(), height: this.height()}).
+        appendTo(data.parent);
+
+    return gradient;
+
+  },
+
+  type: function () {
+    
+    return this.data().f.effect;
+
+  },
+
+  resize: function(full) {
+    
+    var data = this.data().f,
+      turnData = data.opts.turn.data(),
+      width = this.width(),
+      height = this.height();
+
+    switch (data.effect) {
+      case 'hard':
+        
+      if (full) {
+        data.wrapper.css({width: width, height: height});
+        data.fpage.css({width: width, height: height});
+        if (turnData.opts.gradients) {
+          data.ashadow.css({width: width, height: height});
+          data.bshadow.css({width: width, height: height});
+        }
+      }
+
+      break;
+      case 'sheet':
+
+      if (full) {
+        var size = Math.round(Math.sqrt(Math.pow(width, 2)+Math.pow(height, 2)));
+
+        data.wrapper.css({width: size, height: size});
+        data.fwrapper.css({width: size, height: size}).
+          children(':first-child').
+          css({width: width, height: height});
+
+        data.fpage.css({width: width, height: height});
+
+        if (turnData.opts.gradients)
+          data.ashadow.css({width: width, height: height});
+
+        if (flipMethods._backGradient.call(this))
+          data.bshadow.css({width: width, height: height});
+      }
+
+      if (data.parent.is(':visible')) {
+        var offset = findPos(data.parent[0]);
+
+        data.fwrapper.css({top: offset.top,
+          left: offset.left});
+
+        //if (data.opts.turn) {
+         offset = findPos(data.opts.turn[0]);
+         data.fparent.css({top: -offset.top, left: -offset.left});
+        //}
+      }
+
+      this.flip('z', data.opts['z-index']);
+
+      break;
+    }
+
+  },
+
+  // Prepares the page by adding a general wrapper and another objects
+
+  _addPageWrapper: function() {
+
+    var att,
+      data = this.data().f,
+      turnData = data.opts.turn.data(),
+      parent = this.parent();
+
+    data.parent = parent;
+
+  if (!data.wrapper)
+    switch (data.effect) {
+      case 'hard':
+        
+        var cssProperties = {};
+        cssProperties[vendor + 'transform-style'] = 'preserve-3d';
+        cssProperties[vendor + 'backface-visibility'] = 'hidden';
+
+        data.wrapper = $('<div/>', divAtt(0, 0, 2)).
+          css(cssProperties).
+          appendTo(parent).
+          prepend(this);
+
+        data.fpage = $('<div/>', divAtt(0, 0, 1)).
+          css(cssProperties).
+          appendTo(parent);
+        
+        if (turnData.opts.gradients) {
+          data.ashadow = $('<div/>', divAtt(0, 0,  0)).
+            hide().
+            appendTo(parent);
+
+          data.bshadow = $('<div/>', divAtt(0, 0,  0));
+        }
+
+      break;
+      case 'sheet':
+        
+        var width = this.width(),
+          height = this.height(),
+          size = Math.round(Math.sqrt(Math.pow(width, 2)+Math.pow(height, 2)));
+        
+        data.fparent = data.opts.turn.data().fparent;
+
+        if (!data.fparent) {
+          var fparent = $('<div/>', {css: {'pointer-events': 'none'}}).hide();
+            fparent.data().flips = 0;
+            fparent.css(divAtt(0, 0, 'auto', 'visible').css).
+            appendTo(data.opts.turn);
+            
+            data.opts.turn.data().fparent = fparent;
+            data.fparent = fparent;
+        }
+
+        this.css({position: 'absolute', top: 0, left: 0, bottom: 'auto', right: 'auto'});
+
+        data.wrapper = $('<div/>', divAtt(0, 0, this.css('z-index'))).
+          appendTo(parent).
+          prepend(this);
+
+        data.fwrapper = $('<div/>', divAtt(parent.offset().top, parent.offset().left)).
+          hide().
+          appendTo(data.fparent);
+
+        data.fpage = $('<div/>', divAtt(0, 0, 0, 'visible')).
+          css({cursor: 'default'}).
+          appendTo(data.fwrapper);
+
+        if (turnData.opts.gradients)
+          data.ashadow = $('<div/>', divAtt(0, 0,  1)).
+          appendTo(data.fpage);
+
+        flipMethods.setData.call(this, data);
+
+      break;
+    }
+
+    // Set size
+    flipMethods.resize.call(this, true);
+
+  },
+
+  // Takes a 2P point from the screen and applies the transformation
+
+  _fold: function(point) {
+
+    var data = this.data().f,
+      turnData = data.opts.turn.data(),
+      o = flipMethods._c.call(this, point.corner),
+      width = this.width(),
+      height = this.height();
+
+    switch (data.effect) {
+
+      case 'hard':
+
+        if (point.corner=='l')
+          point.x = Math.min(Math.max(point.x, 0), width*2);
+        else
+          point.x = Math.max(Math.min(point.x, width), -width);
+
+        var leftPos,
+          shadow,
+          gradientX,
+          fpageOrigin,
+          parentOrigin,
+          totalPages = turnData.totalPages,
+          zIndex = data.opts['z-index'] || totalPages,
+          parentCss = {'overflow': 'visible'},
+          relX = (o.x) ? (o.x - point.x)/width : point.x/width,
+          angle = relX * 90,
+          half = angle<90;
+
+        switch (point.corner) {
+          case 'l':
+
+            fpageOrigin =  '0% 50%';
+            parentOrigin =  '100% 50%';
+
+            if (half) {
+              leftPos = 0;
+              shadow = data.opts.next-1>0;
+              gradientX = 1;
+            } else {
+              leftPos = '100%';
+              shadow = data.opts.page+1<totalPages;
+              gradientX = 0;
+            }
+
+          break;
+          case 'r':
+
+            fpageOrigin =  '100% 50%';
+            parentOrigin =  '0% 50%';
+            angle = -angle;
+            width = -width;
+
+            if (half) {
+              leftPos = 0;
+              shadow = data.opts.next+1<totalPages;
+              gradientX = 0;
+            } else {
+              leftPos = '-100%';
+              shadow = data.opts.page!=1;
+              gradientX = 1;
+            }
+
+          break;
+        }
+
+        parentCss[vendor+'perspective-origin'] = parentOrigin;
+
+        data.wrapper.transform('rotateY('+angle+'deg)' +
+          'translate3d(0px, 0px, '+(this.attr('depth')||0)+'px)', parentOrigin);
+
+        data.fpage.transform('translateX('+width+'px) rotateY('+(180+angle)+'deg)', fpageOrigin);
+
+        data.parent.css(parentCss);
+
+        if (half) {
+          relX = -relX+1;
+          data.wrapper.css({zIndex: zIndex+1});
+          data.fpage.css({zIndex: zIndex});
+        } else {
+          relX = relX-1;
+          data.wrapper.css({zIndex: zIndex});
+          data.fpage.css({zIndex: zIndex+1});
+        }
+
+        if (turnData.opts.gradients) {
+          if (shadow)
+            data.ashadow.css({
+              display: '',
+              left: leftPos,
+              backgroundColor: 'rgba(0,0,0,'+(0.5*relX)+')'
+            }).
+            transform('rotateY(0deg)');
+          else
+            data.ashadow.hide();
+
+          data.bshadow.css({opacity:-relX + 1});
+
+          if (half) {
+            if (data.bshadow.parent()[0]!=data.wrapper[0]) {
+              data.bshadow.appendTo(data.wrapper);
+            }
+          } else {
+            if (data.bshadow.parent()[0]!=data.fpage[0]) {
+              data.bshadow.appendTo(data.fpage);
+            }
+          }
+          /*data.bshadow.css({
+            backgroundColor: 'rgba(0,0,0,'+(0.1)+')'
+          })*/
+          gradient(data.bshadow, point2D(gradientX * 100, 0), point2D((-gradientX + 1)*100, 0),
+            [[0, 'rgba(0,0,0,0.3)'],[1, 'rgba(0,0,0,0)']],2);
+          
+        }
+
+        break;
+      case 'sheet':
+
+        var that = this,
+          a = 0,
+          alpha = 0,
+          beta,
+          px,
+          gradientEndPointA,
+          gradientEndPointB,
+          gradientStartVal,
+          gradientSize,
+          gradientOpacity,
+          shadowVal,
+          mv = point2D(0, 0),
+          df = point2D(0, 0),
+          tr = point2D(0, 0),
+          folding = flipMethods._foldingPage.call(this),
+          tan = Math.tan(alpha),
+          ac = turnData.opts.acceleration,
+          h = data.wrapper.height(),
+          top = point.corner.substr(0, 1) == 't',
+          left = point.corner.substr(1, 1) == 'l',
+
+      compute = function() {
+
+        var rel = point2D(0, 0);
+        var middle = point2D(0, 0);
+
+        rel.x = (o.x) ? o.x - point.x : point.x;
+
+        if (!hasRot) {
+          rel.y = 0;
+        } else {
+          rel.y = (o.y) ? o.y - point.y : point.y;
+        }
+
+        middle.x = (left)? width - rel.x/2 : point.x + rel.x/2;
+        middle.y = rel.y/2;
+        
+        var alpha =  A90-Math.atan2(rel.y, rel.x),
+          gamma = alpha - Math.atan2(middle.y, middle.x),
+          distance =  Math.max(0, Math.sin(gamma) * Math.sqrt(Math.pow(middle.x, 2) + Math.pow(middle.y, 2)));
+          
+          a = deg(alpha);
+
+          tr = point2D(distance * Math.sin(alpha), distance * Math.cos(alpha));
+
+          if (alpha > A90) {
+            tr.x = tr.x + Math.abs(tr.y * rel.y/rel.x);
+            tr.y = 0;
+            if (Math.round(tr.x*Math.tan(PI-alpha)) < height) {
+              point.y = Math.sqrt(Math.pow(height, 2)+2 * middle.x * rel.x);
+              if (top) point.y =  height - point.y;
+              return compute();
+            }
+          }
+      
+          if (alpha>A90) {
+            var beta = PI-alpha, dd = h - height/Math.sin(beta);
+            mv = point2D(Math.round(dd*Math.cos(beta)), Math.round(dd*Math.sin(beta)));
+            if (left) mv.x = - mv.x;
+            if (top) mv.y = - mv.y;
+          }
+
+          px = Math.round(tr.y/Math.tan(alpha) + tr.x);
+      
+          var side = width - px,
+            sideX = side*Math.cos(alpha*2),
+            sideY = side*Math.sin(alpha*2);
+            df = point2D(
+              Math.round((left ? side -sideX : px+sideX)),
+              Math.round((top) ? sideY : height - sideY));
+          
+        // Gradients
+          if (turnData.opts.gradients) {
+
+            gradientSize = side*Math.sin(alpha);
+
+            var endingPoint = flipMethods._c2.call(that, point.corner),
+             far = Math.sqrt(Math.pow(endingPoint.x-point.x, 2)+Math.pow(endingPoint.y-point.y, 2))/width;
+
+            shadowVal = Math.sin(A90*((far>1) ? 2 - far : far));
+
+            gradientOpacity = Math.min(far, 1);
+
+           
+              gradientStartVal = gradientSize>100 ? (gradientSize-100)/gradientSize : 0;
+
+              gradientEndPointA = point2D(
+                gradientSize*Math.sin(alpha)/width*100,
+                gradientSize*Math.cos(alpha)/height*100);
+           
+
+              if (flipMethods._backGradient.call(that)) {
+
+                gradientEndPointB = point2D(
+                  gradientSize*1.2*Math.sin(alpha)/width*100,
+                  gradientSize*1.2*Math.cos(alpha)/height*100);
+
+                if (!left) gradientEndPointB.x = 100-gradientEndPointB.x;
+                if (!top) gradientEndPointB.y = 100-gradientEndPointB.y;
+
+              }
+
+          }
+
+          tr.x = Math.round(tr.x);
+          tr.y = Math.round(tr.y);
+
+        return true;
+      },
+
+      transform = function(tr, c, x, a) {
+      
+        var f = ['0', 'auto'], mvW = (width-h)*x[0]/100, mvH = (height-h)*x[1]/100,
+          cssA = {left: f[c[0]], top: f[c[1]], right: f[c[2]], bottom: f[c[3]]},
+          cssB = {},
+          aliasingFk = (a!=90 && a!=-90) ? (left ? -1 : 1) : 0,
+          origin = x[0] + '% ' + x[1] + '%';
+
+        that.css(cssA).
+          transform(rotate(a) + translate(tr.x + aliasingFk, tr.y, ac), origin);
+
+        data.fpage.css(cssA).transform(
+          rotate(a) +
+          translate(tr.x + df.x - mv.x - width*x[0]/100, tr.y + df.y - mv.y - height*x[1]/100, ac) +
+          rotate((180/a - 2)*a),
+          origin);
+
+        data.wrapper.transform(translate(-tr.x + mvW-aliasingFk, -tr.y + mvH, ac) + rotate(-a), origin);
+
+        data.fwrapper.transform(translate(-tr.x + mv.x + mvW, -tr.y + mv.y + mvH, ac) + rotate(-a), origin);
+      
+        if (turnData.opts.gradients) {
+
+          if (x[0])
+            gradientEndPointA.x = 100-gradientEndPointA.x;
+
+          if (x[1])
+            gradientEndPointA.y = (100-gradientEndPointA.y);
+
+          cssB['box-shadow'] = '0 0 20px rgba(0,0,0,'+(0.5*shadowVal)+')';
+          folding.css(cssB);
+
+          gradient(data.ashadow,
+              point2D(left?100:0, top?0:100),
+              point2D(gradientEndPointA.x, gradientEndPointA.y),
+              [[gradientStartVal, 'rgba(0,0,0,0)'],
+              [((1-gradientStartVal)*0.8)+gradientStartVal, 'rgba(0,0,0,'+(0.2*gradientOpacity)+')'],
+              [1, 'rgba(255,255,255,'+(0.2*gradientOpacity)+')']],
+              3,
+              alpha);
+
+          if (flipMethods._backGradient.call(that))
+            gradient(data.bshadow,
+                point2D(left?0:100, top?0:100),
+                point2D(gradientEndPointB.x, gradientEndPointB.y),
+                [[0.6, 'rgba(0,0,0,0)'],
+                [0.8, 'rgba(0,0,0,'+(0.3*gradientOpacity)+')'],
+                [1, 'rgba(0,0,0,0)']
+                ],
+                3);
+        }
+
+      };
+
+      switch (point.corner) {
+        case 'l' :
+
+
+        break;
+        case 'r' :
+
+
+        break;
+        case 'tl' :
+          point.x = Math.max(point.x, 1);
+          compute();
+          transform(tr, [1,0,0,1], [100, 0], a);
+        break;
+        case 'tr' :
+          point.x = Math.min(point.x, width-1);
+          compute();
+          transform(point2D(-tr.x, tr.y), [0,0,0,1], [0, 0], -a);
+        break;
+        case 'bl' :
+          point.x = Math.max(point.x, 1);
+          compute();
+          transform(point2D(tr.x, -tr.y), [1,1,0,0], [100, 100], -a);
+        break;
+        case 'br' :
+          point.x = Math.min(point.x, width-1);
+          compute();
+          transform(point2D(-tr.x, -tr.y), [0,1,1,0], [0, 100], a);
+        break;
+      }
+
+    break;
+  }
+
+    data.point = point;
+  
+  },
+
+  _moveFoldingPage: function(move) {
+
+    var data = this.data().f;
+
+    if (!data)
+      return;
+
+    var turn = data.opts.turn,
+      turnData = turn.data(),
+      place = turnData.pagePlace;
+      
+    if (move) {
+
+      var nextPage = data.opts.next;
+  
+      if (place[nextPage]!=data.opts.page) {
+
+        if (data.folding)
+          flipMethods._moveFoldingPage.call(this, false);
+
+        var folding = flipMethods._foldingPage.call(this);
+        
+        folding.appendTo(data.fpage);
+        place[nextPage] = data.opts.page;
+        data.folding = nextPage;
+      }
+
+      turn.turn('update');
+
+    } else {
+
+      if (data.folding) {
+
+        if (turnData.pages[data.folding]) {
+         
+          // If we have flip available
+
+          var flipData = turnData.pages[data.folding].data().f;
+          
+          turnData.pageObjs[data.folding].
+            appendTo(flipData.wrapper);
+
+        } else if (turnData.pageWrap[data.folding]) {
+          
+          // If we have the pageWrapper
+
+          turnData.pageObjs[data.folding].
+            appendTo(turnData.pageWrap[data.folding]);
+
+        }
+
+        if (data.folding in place) {
+          place[data.folding] = data.folding;
+        }
+
+        delete data.folding;
+
+      }
+    }
+  },
+
+  _showFoldedPage: function(c, animate) {
+
+    var folding = flipMethods._foldingPage.call(this),
+      dd = this.data(),
+      data = dd.f,
+      visible = data.visible;
+
+    if (folding) {
+
+      if (!visible || !data.point || data.point.corner!=c.corner) {
+
+        var corner = (
+          data.status=='hover' ||
+          data.status=='peel' ||
+          data.opts.turn.data().mouseAction) ?
+        c.corner : null;
+
+        visible = false;
+
+        if (trigger('start', this, [data.opts, corner])=='prevented')
+          return false;
+
+      }
+
+      if (animate) {
+        
+        var that = this,
+          point = (data.point && data.point.corner==c.corner) ?
+          data.point : flipMethods._c.call(this, c.corner, 1);
+      
+        this.animatef({
+          from: [point.x, point.y],
+          to: [c.x, c.y],
+          duration: 500,
+          frame: function(v) {
+            c.x = Math.round(v[0]);
+            c.y = Math.round(v[1]);
+            flipMethods._fold.call(that, c);
+          }
+        });
+
+      } else  {
+
+        flipMethods._fold.call(this, c);
+
+        if (dd.effect && !dd.effect.turning)
+          this.animatef(false);
+
+      }
+
+      if (!visible) {
+
+        switch(data.effect) {
+          case 'hard':
+
+            data.visible = true;
+            flipMethods._moveFoldingPage.call(this, true);
+            data.fpage.show();
+            if (data.opts.shadows)
+              data.bshadow.show();
+
+          break;
+          case 'sheet':
+
+            data.visible = true;
+            data.fparent.show().data().flips++;
+            flipMethods._moveFoldingPage.call(this, true);
+            data.fwrapper.show();
+            if (data.bshadow)
+              data.bshadow.show();
+
+          break;
+        }
+
+      }
+
+      return true;
+
+    }
+
+    return false;
+  },
+
+  hide: function() {
+
+    var data = this.data().f,
+      turnData = data.opts.turn.data(),
+      folding = flipMethods._foldingPage.call(this);
+
+    switch (data.effect) {
+      case 'hard':
+        
+        if (turnData.opts.gradients) {
+          data.bshadowLoc = 0;
+          data.bshadow.remove();
+          data.ashadow.hide();
+        }
+
+        data.wrapper.transform('');
+        data.fpage.hide();
+
+      break;
+      case 'sheet':
+
+        if ((--data.fparent.data().flips)===0)
+          data.fparent.hide();
+
+        this.css({left: 0, top: 0, right: 'auto', bottom: 'auto'}).
+          transform('');
+
+        data.wrapper.transform('');
+
+        data.fwrapper.hide();
+
+        if (data.bshadow)
+          data.bshadow.hide();
+
+        folding.transform('');
+
+      break;
+    }
+
+      data.visible = false;
+
+    return this;
+  },
+
+  hideFoldedPage: function(animate) {
+
+    var data = this.data().f;
+
+    if (!data.point) return;
+
+    var that = this,
+      p1 = data.point,
+      hide = function() {
+        data.point = null;
+        data.status = '';
+        that.flip('hide');
+        that.trigger('end', [data.opts, false]);
+      };
+
+    if (animate) {
+
+      var p4 = flipMethods._c.call(this, p1.corner),
+        top = (p1.corner.substr(0,1)=='t'),
+        delta = (top) ? Math.min(0, p1.y-p4.y)/2 : Math.max(0, p1.y-p4.y)/2,
+        p2 = point2D(p1.x, p1.y+delta),
+        p3 = point2D(p4.x, p4.y-delta);
+    
+      this.animatef({
+        from: 0,
+        to: 1,
+        frame: function(v) {
+          var np = bezier(p1, p2, p3, p4, v);
+          p1.x = np.x;
+          p1.y = np.y;
+          flipMethods._fold.call(that, p1);
+        },
+        complete: hide,
+        duration: 800,
+        hiding: true
+      });
+
+    } else {
+
+      this.animatef(false);
+      hide();
+
+    }
+  },
+
+  turnPage: function(corner) {
+
+    var that = this,
+      data = this.data().f,
+      turnData = data.opts.turn.data();
+
+    corner = {corner: (data.corner) ?
+      data.corner.corner :
+      corner || flipMethods._cAllowed.call(this)[0]};
+
+    var p1 = data.point ||
+      flipMethods._c.call(this,
+        corner.corner,
+        (data.opts.turn) ? turnData.opts.elevation : 0),
+      p4 = flipMethods._c2.call(this, corner.corner);
+
+      this.trigger('flip').
+        animatef({
+          from: 0,
+          to: 1,
+          frame: function(v) {
+
+            var np = bezier(p1, p1, p4, p4, v);
+            corner.x = np.x;
+            corner.y = np.y;
+            flipMethods._showFoldedPage.call(that, corner);
+
+          },
+          complete: function() {
+            
+            that.trigger('end', [data.opts, true]);
+
+          },
+          duration: turnData.opts.duration,
+          turning: true
+        });
+
+      data.corner = null;
+  },
+
+  moving: function() {
+
+    return 'effect' in this.data();
+  
+  },
+
+  isTurning: function() {
+
+    return this.flip('moving') && this.data().effect.turning;
+  
+  },
+
+  corner: function() {
+    
+    return this.data().f.corner;
+      
+  },
+
+  _eventStart: function(e) {
+
+    var data = this.data().f,
+      turn = data.opts.turn;
+
+    if (!data.corner && !data.disabled && !this.flip('isTurning') &&
+      data.opts.page==turn.data().pagePlace[data.opts.page])
+    {
+
+      data.corner = flipMethods._isIArea.call(this, e);
+
+      if (data.corner && flipMethods._foldingPage.call(this)) {
+
+        this.trigger('pressed', [data.point]);
+        flipMethods._showFoldedPage.call(this, data.corner);
+
+        return false;
+
+      } else
+        data.corner = null;
+
+    }
+
+  },
+
+  _eventMove: function(e) {
+
+    var data = this.data().f;
+
+    if (!data.disabled) {
+
+      e = (isTouch) ? e.originalEvent.touches : [e];
+
+      if (data.corner) {
+
+        var pos = data.parent.offset();
+        data.corner.x = e[0].pageX-pos.left;
+        data.corner.y = e[0].pageY-pos.top;
+        flipMethods._showFoldedPage.call(this, data.corner);
+
+      } else if (data.hover && !this.data().effect && this.is(':visible')) {
+
+        var point = flipMethods._isIArea.call(this, e[0]);
+
+        if (point) {
+
+          if ((data.effect=='sheet' && point.corner.length==2)  || data.effect=='hard') {
+            data.status = 'hover';
+            var origin = flipMethods._c.call(this, point.corner, data.opts.cornerSize/2);
+            point.x = origin.x;
+            point.y = origin.y;
+            flipMethods._showFoldedPage.call(this, point, true);
+          }
+        
+        } else {
+          
+          if (data.status=='hover') {
+            data.status = '';
+            flipMethods.hideFoldedPage.call(this, true);
+          }
+
+        }
+
+      }
+
+    }
+
+  },
+
+  _eventEnd: function() {
+
+    var data = this.data().f,
+      corner = data.corner;
+
+    if (!data.disabled && corner) {
+      if (trigger('released', this, [data.point || corner])!='prevented') {
+        flipMethods.hideFoldedPage.call(this, true);
+      }
+    }
+
+    data.corner = null;
+
+  },
+
+  disable: function(disable) {
+
+    flipMethods.setData.call(this, {'disabled': disable});
+    return this;
+
+  },
+
+  hover: function(hover) {
+    
+    flipMethods.setData.call(this, {'hover': hover});
+    return this;
+
+  },
+
+  peel: function (corner, animate) {
+
+    var data = this.data().f;
+
+    if (corner) {
+
+      if ($.inArray(corner, corners.all)==-1)
+        throw turnError('Corner '+corner+' is not permitted');
+
+      if ($.inArray(corner, flipMethods._cAllowed.call(this))!=-1) {
+
+        var point = flipMethods._c.call(this, corner, data.opts.cornerSize/2);
+        
+        data.status = 'peel';
+
+        flipMethods._showFoldedPage.call(this,
+        {
+          corner: corner,
+          x: point.x,
+          y: point.y
+        }, animate);
+
+      }
+
+
+    } else {
+
+      data.status = '';
+
+      flipMethods.hideFoldedPage.call(this, animate);
+      
+    }
+
+    return this;
+  }
+};
+
+
+// Processes classes
+
+function dec(that, methods, args) {
+
+  if (!args[0] || typeof(args[0])=='object')
+    return methods.init.apply(that, args);
+
+  else if (methods[args[0]])
+    return methods[args[0]].apply(that, Array.prototype.slice.call(args, 1));
+
+  else
+    throw turnError(args[0] + ' is not a method or property');
+
+}
+
+
+// Attributes for a layer
+
+function divAtt(top, left, zIndex, overf) {
+    
+  return {'css': {
+    position: 'absolute',
+    top: top,
+    left: left,
+    'overflow': overf || 'hidden',
+    zIndex: zIndex || 'auto'
+  }
+};
+      
+}
+
+// Gets a 2D point from a bezier curve of four points
+
+function bezier(p1, p2, p3, p4, t) {
+
+  var a = 1 - t,
+    b = a * a * a,
+    c = t * t * t;
+    
+  return point2D(Math.round(b*p1.x + 3*t*a*a*p2.x + 3*t*t*a*p3.x + c*p4.x),
+    Math.round(b*p1.y + 3*t*a*a*p2.y + 3*t*t*a*p3.y + c*p4.y));
+
+}
+  
+// Converts an angle from degrees to radians
+
+function rad(degrees) {
+  
+  return degrees/180*PI;
+
+}
+
+// Converts an angle from radians to degrees
+
+function deg(radians) {
+  
+  return radians/PI*180;
+
+}
+
+// Gets a 2D point
+
+function point2D(x, y) {
+  
+  return {x: x, y: y};
+
+}
+
+// Webkit 534.3 on Android wrongly repaints elements that use overflow:hidden + rotation
+
+function rotationAvailable() {
+  var parts;
+
+  if ((parts = /AppleWebkit\/([0-9\.]+)/i.exec(navigator.userAgent))) {
+    var webkitVersion = parseFloat(parts[1]);
+    return (webkitVersion>534.3);
+  } else {
+    return true;
+  }
+}
+
+// Returns the traslate value
+
+function translate(x, y, use3d) {
+  
+  return (has3d && use3d) ? ' translate3d(' + x + 'px,' + y + 'px, 0px) '
+  : ' translate(' + x + 'px, ' + y + 'px) ';
+
+}
+
+// Returns the rotation value
+
+function rotate(degrees) {
+  
+  return ' rotate(' + degrees + 'deg) ';
+
+}
+
+// Checks if a property belongs to an object
+
+function has(property, object) {
+  
+  return Object.prototype.hasOwnProperty.call(object, property);
+
+}
+
+// Gets the CSS3 vendor prefix
+
+function getPrefix() {
+
+  var vendorPrefixes = ['Moz','Webkit','Khtml','O','ms'],
+  len = vendorPrefixes.length,
+  vendor = '';
+
+  while (len--)
+    if ((vendorPrefixes[len] + 'Transform') in document.body.style)
+      vendor='-'+vendorPrefixes[len].toLowerCase()+'-';
+
+  return vendor;
+
+}
+
+// Detects the transitionEnd Event
+
+function getTransitionEnd() {
+
+  var t,
+    el = document.createElement('fakeelement'),
+    transitions = {
+      'transition':'transitionend',
+      'OTransition':'oTransitionEnd',
+      'MSTransition':'transitionend',
+      'MozTransition':'transitionend',
+      'WebkitTransition':'webkitTransitionEnd'
+    };
+
+  for (t in transitions) {
+    if (el.style[t] !== undefined) {
+      return transitions[t];
+    }
+  }
+}
+
+// Gradients
+
+function gradient(obj, p0, p1, colors, numColors) {
+
+  var j, cols = [];
+
+  if (vendor=='-webkit-') {
+
+    for (j = 0; j<numColors; j++)
+      cols.push('color-stop('+colors[j][0]+', '+colors[j][1]+')');
+    
+    obj.css({'background-image':
+        '-webkit-gradient(linear, '+
+        p0.x+'% '+
+        p0.y+'%,'+
+        p1.x+'% '+
+        p1.y+'%, '+
+        cols.join(',') + ' )'});
+  } else {
+    
+    p0 = {x:p0.x/100 * obj.width(), y:p0.y/100 * obj.height()};
+    p1 = {x:p1.x/100 * obj.width(), y:p1.y/100 * obj.height()};
+
+    var dx = p1.x-p0.x,
+      dy = p1.y-p0.y,
+      angle = Math.atan2(dy, dx),
+      angle2 = angle - Math.PI/2,
+      diagonal = Math.abs(obj.width()*Math.sin(angle2))+Math.abs(obj.height()*Math.cos(angle2)),
+      gradientDiagonal = Math.sqrt(dy*dy + dx*dx),
+      corner = point2D((p1.x<p0.x) ? obj.width() : 0, (p1.y<p0.y) ? obj.height() : 0),
+      slope = Math.tan(angle),
+      inverse = -1/slope,
+      x = (inverse*corner.x - corner.y - slope*p0.x + p0.y)/(inverse-slope),
+      c = {x: x, y: inverse*x - inverse*corner.x + corner.y},
+      segA = (Math.sqrt( Math.pow(c.x-p0.x,2) + Math.pow(c.y-p0.y,2)));
+
+      for (j = 0; j<numColors; j++)
+        cols.push(' '+colors[j][1]+' '+((segA + gradientDiagonal*colors[j][0])*100/diagonal)+'%');
+
+      obj.css({'background-image': vendor+'linear-gradient(' + (-angle) + 'rad,' + cols.join(',') + ')'});
+  }
+}
+
+
+// Triggers an event
+
+function trigger(eventName, context, args) {
+
+  var event = $.Event(eventName);
+  context.trigger(event, args);
+  if (event.isDefaultPrevented())
+    return 'prevented';
+  else if (event.isPropagationStopped())
+    return 'stopped';
+  else
+    return '';
+}
+
+// JS Errors
+
+function turnError(message) {
+
+  function TurnJsError(message) {
+    this.name = "TurnJsError";
+    this.message = message;
+  }
+
+  TurnJsError.prototype = new Error();
+  TurnJsError.prototype.constructor = TurnJsError;
+  return new TurnJsError(message);
+
+}
+
+// Find the offset of an element ignoring its transformation
+
+function findPos(obj) {
+
+  var offset = {top: 0, left: 0};
+
+  do{
+    offset.left += obj.offsetLeft;
+    offset.top += obj.offsetTop;
+  } while ((obj = obj.offsetParent));
+
+  return offset;
+
+}
+
+// Checks if there's hard page compatibility
+// IE9 is the only browser that does not support hard pages
+
+function hasHardPage() {
+  return (navigator.userAgent.indexOf('MSIE 9.0')==-1);
+}
+
+// Request an animation
+
+window.requestAnim = (function() {
+  return window.requestAnimationFrame ||
+    window.webkitRequestAnimationFrame ||
+    window.mozRequestAnimationFrame ||
+    window.oRequestAnimationFrame ||
+    window.msRequestAnimationFrame ||
+    function(callback) {
+      window.setTimeout(callback, 1000 / 60);
+    };
+
+})();
+
+// Extend $.fn
+
+$.extend($.fn, {
+
+  flip: function() {
+    return dec($(this[0]), flipMethods, arguments);
+  },
+
+  turn: function() {
+    return dec($(this[0]), turnMethods, arguments);
+  },
+
+  transform: function(transform, origin) {
+
+    var properties = {};
+    
+    if (origin)
+      properties[vendor+'transform-origin'] = origin;
+    
+    properties[vendor+'transform'] = transform;
+  
+    return this.css(properties);
+
+  },
+
+  animatef: function(point) {
+
+    var data = this.data();
+
+    if (data.effect)
+      data.effect.stop();
+
+    if (point) {
+
+      if (!point.to.length) point.to = [point.to];
+      if (!point.from.length) point.from = [point.from];
+
+      var diff = [],
+        len = point.to.length,
+        animating = true,
+        that = this,
+        time = (new Date()).getTime(),
+        frame = function() {
+
+          if (!data.effect || !animating)
+            return;
+
+          var v = [],
+            timeDiff = Math.min(point.duration, (new Date()).getTime() - time);
+
+          for (var i = 0; i < len; i++)
+            v.push(data.effect.easing(1, timeDiff, point.from[i], diff[i], point.duration));
+
+          point.frame((len==1) ? v[0] : v);
+
+          if (timeDiff==point.duration) {
+            delete data['effect'];
+            that.data(data);
+            if (point.complete)
+              point.complete();
+          } else {
+            window.requestAnim(frame);
+          }
+        };
+
+      for (var i = 0; i < len; i++)
+        diff.push(point.to[i] - point.from[i]);
+
+      data.effect = $.extend({
+        stop: function() {
+          animating = false;
+        },
+        easing: function (x, t, b, c, data) {
+          return c * Math.sqrt(1 - (t=t/data-1)*t) + b;
+        }
+      }, point);
+
+      this.data(data);
+
+      frame();
+
+    } else {
+      
+      delete data['effect'];
+
+    }
+  }
+});
+
+// Export some globals
+
+$.isTouch = isTouch;
+$.mouseEvents = mouseEvents;
+$.cssPrefix = getPrefix;
+$.cssTransitionEnd = getTransitionEnd;
+$.findPos = findPos;
+
+})(jQuery);

+ 68 - 0
public/book/turn.min.js

@@ -0,0 +1,68 @@
+/* turn.js 4.1.0 | Copyright (c) 2012 Emmanuel Garcia | turnjs.com | turnjs.com/license.txt */
+
+(function(f){function J(a,b,c){if(!c[0]||"object"==typeof c[0])return b.init.apply(a,c);if(b[c[0]])return b[c[0]].apply(a,Array.prototype.slice.call(c,1));throw q(c[0]+" is not a method or property");}function l(a,b,c,d){return{css:{position:"absolute",top:a,left:b,overflow:d||"hidden",zIndex:c||"auto"}}}function S(a,b,c,d,e){var h=1-e,f=h*h*h,g=e*e*e;return j(Math.round(f*a.x+3*e*h*h*b.x+3*e*e*h*c.x+g*d.x),Math.round(f*a.y+3*e*h*h*b.y+3*e*e*h*c.y+g*d.y))}function j(a,b){return{x:a,y:b}}function F(a,
+b,c){return z&&c?" translate3d("+a+"px,"+b+"px, 0px) ":" translate("+a+"px, "+b+"px) "}function G(a){return" rotate("+a+"deg) "}function n(a,b){return Object.prototype.hasOwnProperty.call(b,a)}function T(){for(var a=["Moz","Webkit","Khtml","O","ms"],b=a.length,c="";b--;)a[b]+"Transform"in document.body.style&&(c="-"+a[b].toLowerCase()+"-");return c}function P(a,b,c,d,e){var h,f=[];if("-webkit-"==w){for(h=0;h<e;h++)f.push("color-stop("+d[h][0]+", "+d[h][1]+")");a.css({"background-image":"-webkit-gradient(linear, "+
+b.x+"% "+b.y+"%,"+c.x+"% "+c.y+"%, "+f.join(",")+" )"})}else{var b={x:b.x/100*a.width(),y:b.y/100*a.height()},c={x:c.x/100*a.width(),y:c.y/100*a.height()},g=c.x-b.x;h=c.y-b.y;var i=Math.atan2(h,g),x=i-Math.PI/2,x=Math.abs(a.width()*Math.sin(x))+Math.abs(a.height()*Math.cos(x)),g=Math.sqrt(h*h+g*g),c=j(c.x<b.x?a.width():0,c.y<b.y?a.height():0),k=Math.tan(i);h=-1/k;k=(h*c.x-c.y-k*b.x+b.y)/(h-k);c=h*k-h*c.x+c.y;b=Math.sqrt(Math.pow(k-b.x,2)+Math.pow(c-b.y,2));for(h=0;h<e;h++)f.push(" "+d[h][1]+" "+100*
+(b+g*d[h][0])/x+"%");a.css({"background-image":w+"linear-gradient("+-i+"rad,"+f.join(",")+")"})}}function t(a,b,c){a=f.Event(a);b.trigger(a,c);return a.isDefaultPrevented()?"prevented":a.isPropagationStopped()?"stopped":""}function q(a){function b(a){this.name="TurnJsError";this.message=a}b.prototype=Error();b.prototype.constructor=b;return new b(a)}function D(a){var b={top:0,left:0};do b.left+=a.offsetLeft,b.top+=a.offsetTop;while(a=a.offsetParent);return b}var z,U,w="",K=Math.PI,L=K/2,u="ontouchstart"in
+window,r=u?{down:"touchstart",move:"touchmove",up:"touchend",over:"touchstart",out:"touchend"}:{down:"mousedown",move:"mousemove",up:"mouseup",over:"mouseover",out:"mouseout"},p={backward:["bl","tl"],forward:["br","tr"],all:"tl bl tr br l r".split(" ")},V=["single","double"],W=["ltr","rtl"],X={acceleration:!0,display:"double",duration:600,page:1,gradients:!0,turnCorners:"bl,br",when:null},Y={cornerSize:100},g={init:function(a){z="WebKitCSSMatrix"in window||"MozPerspective"in document.body.style;var b;
+U=(b=/AppleWebkit\/([0-9\.]+)/i.exec(navigator.userAgent))?534.3<parseFloat(b[1]):!0;w=T();var c;b=0;var d=this.data(),e=this.children(),a=f.extend({width:this.width(),height:this.height(),direction:this.attr("dir")||this.css("direction")||"ltr"},X,a);d.opts=a;d.pageObjs={};d.pages={};d.pageWrap={};d.pageZoom={};d.pagePlace={};d.pageMv=[];d.zoom=1;d.totalPages=a.pages||0;d.eventHandlers={touchStart:f.proxy(g._touchStart,this),touchMove:f.proxy(g._touchMove,this),touchEnd:f.proxy(g._touchEnd,this),
+start:f.proxy(g._eventStart,this)};if(a.when)for(c in a.when)n(c,a.when)&&this.bind(c,a.when[c]);this.css({position:"relative",width:a.width,height:a.height});this.turn("display",a.display);""!==a.direction&&this.turn("direction",a.direction);z&&(!u&&a.acceleration)&&this.transform(F(0,0,!0));for(c=0;c<e.length;c++)"1"!=f(e[c]).attr("ignore")&&this.turn("addPage",e[c],++b);f(this).bind(r.down,d.eventHandlers.touchStart).bind("end",g._eventEnd).bind("pressed",g._eventPressed).bind("released",g._eventReleased).bind("flip",
+g._flip);f(this).parent().bind("start",d.eventHandlers.start);f(document).bind(r.move,d.eventHandlers.touchMove).bind(r.up,d.eventHandlers.touchEnd);this.turn("page",a.page);d.done=!0;return this},addPage:function(a,b){var c,d=!1,e=this.data(),h=e.totalPages+1;if(e.destroying)return!1;if(c=/\bp([0-9]+)\b/.exec(f(a).attr("class")))b=parseInt(c[1],10);if(b)if(b==h)d=!0;else{if(b>h)throw q('Page "'+b+'" cannot be inserted');}else b=h,d=!0;1<=b&&b<=h&&(c="double"==e.display?b%2?" odd":" even":"",e.done&&
+this.turn("stop"),b in e.pageObjs&&g._movePages.call(this,b,1),d&&(e.totalPages=h),e.pageObjs[b]=f(a).css({"float":"left"}).addClass("page p"+b+c),-1!=navigator.userAgent.indexOf("MSIE 9.0")&&e.pageObjs[b].hasClass("hard")&&e.pageObjs[b].removeClass("hard"),g._addPage.call(this,b),g._removeFromDOM.call(this));return this},_addPage:function(a){var b=this.data(),c=b.pageObjs[a];if(c)if(g._necessPage.call(this,a)){if(!b.pageWrap[a]){b.pageWrap[a]=f("<div/>",{"class":"page-wrapper",page:a,css:{position:"absolute",
+overflow:"hidden"}});this.append(b.pageWrap[a]);b.pagePlace[a]||(b.pagePlace[a]=a,b.pageObjs[a].appendTo(b.pageWrap[a]));var d=g._pageSize.call(this,a,!0);c.css({width:d.width,height:d.height});b.pageWrap[a].css(d)}b.pagePlace[a]==a&&g._makeFlip.call(this,a)}else b.pagePlace[a]=0,b.pageObjs[a]&&b.pageObjs[a].remove()},hasPage:function(a){return n(a,this.data().pageObjs)},center:function(a){var b=this.data(),c=f(this).turn("size"),d=0;b.noCenter||("double"==b.display&&(a=this.turn("view",a||b.tpage||
+b.page),"ltr"==b.direction?a[0]?a[1]||(d+=c.width/4):d-=c.width/4:a[0]?a[1]||(d-=c.width/4):d+=c.width/4),f(this).css({marginLeft:d}));return this},destroy:function(){var a=this,b=this.data(),c="end first flip last pressed released start turning turned zooming missing".split(" ");if("prevented"!=t("destroying",this)){b.destroying=!0;f.each(c,function(b,c){a.unbind(c)});this.parent().unbind("start",b.eventHandlers.start);for(f(document).unbind(r.move,b.eventHandlers.touchMove).unbind(r.up,b.eventHandlers.touchEnd);0!==
+b.totalPages;)this.turn("removePage",b.totalPages);b.fparent&&b.fparent.remove();b.shadow&&b.shadow.remove();this.removeData();b=null;return this}},is:function(){return"object"==typeof this.data().pages},zoom:function(a){var b=this.data();if("number"==typeof a){if(0.0010>a||100<a)throw q(a+" is not a value for zoom");if("prevented"==t("zooming",this,[a,b.zoom]))return this;var c=this.turn("size"),d=this.turn("view"),e=1/b.zoom,h=Math.round(c.width*e*a),c=Math.round(c.height*e*a);b.zoom=a;f(this).turn("stop").turn("size",
+h,c);b.opts.autoCenter&&this.turn("center");g._updateShadow.call(this);for(a=0;a<d.length;a++)d[a]&&b.pageZoom[d[a]]!=b.zoom&&(this.trigger("zoomed",[d[a],d,b.pageZoom[d[a]],b.zoom]),b.pageZoom[d[a]]=b.zoom);return this}return b.zoom},_pageSize:function(a,b){var c=this.data(),d={};if("single"==c.display)d.width=this.width(),d.height=this.height(),b&&(d.top=0,d.left=0,d.right="auto");else{var e=this.width()/2,h=this.height();c.pageObjs[a].hasClass("own-size")?(d.width=c.pageObjs[a].width(),d.height=
+c.pageObjs[a].height()):(d.width=e,d.height=h);if(b){var f=a%2;d.top=(h-d.height)/2;"ltr"==c.direction?(d[f?"right":"left"]=e-d.width,d[f?"left":"right"]="auto"):(d[f?"left":"right"]=e-d.width,d[f?"right":"left"]="auto")}}return d},_makeFlip:function(a){var b=this.data();if(!b.pages[a]&&b.pagePlace[a]==a){var c="single"==b.display,d=a%2;b.pages[a]=b.pageObjs[a].css(g._pageSize.call(this,a)).flip({page:a,next:d||c?a+1:a-1,turn:this}).flip("disable",b.disabled);g._setPageLoc.call(this,a);b.pageZoom[a]=
+b.zoom}return b.pages[a]},_makeRange:function(){var a,b;if(!(1>this.data().totalPages)){b=this.turn("range");for(a=b[0];a<=b[1];a++)g._addPage.call(this,a)}},range:function(a){var b,c,d,e=this.data(),a=a||e.tpage||e.page||1;d=g._view.call(this,a);if(1>a||a>e.totalPages)throw q('"'+a+'" is not a valid page');d[1]=d[1]||d[0];1<=d[0]&&d[1]<=e.totalPages?(a=Math.floor(2),e.totalPages-d[1]>d[0]?(b=Math.min(d[0]-1,a),c=2*a-b):(c=Math.min(e.totalPages-d[1],a),b=2*a-c)):c=b=5;return[Math.max(1,d[0]-b),Math.min(e.totalPages,
+d[1]+c)]},_necessPage:function(a){if(0===a)return!0;var b=this.turn("range");return this.data().pageObjs[a].hasClass("fixed")||a>=b[0]&&a<=b[1]},_removeFromDOM:function(){var a,b=this.data();for(a in b.pageWrap)n(a,b.pageWrap)&&!g._necessPage.call(this,a)&&g._removePageFromDOM.call(this,a)},_removePageFromDOM:function(a){var b=this.data();if(b.pages[a]){var c=b.pages[a].data();i._moveFoldingPage.call(b.pages[a],!1);c.f&&c.f.fwrapper&&c.f.fwrapper.remove();b.pages[a].removeData();b.pages[a].remove();
+delete b.pages[a]}b.pageObjs[a]&&b.pageObjs[a].remove();b.pageWrap[a]&&(b.pageWrap[a].remove(),delete b.pageWrap[a]);g._removeMv.call(this,a);delete b.pagePlace[a];delete b.pageZoom[a]},removePage:function(a){var b=this.data();if("*"==a)for(;0!==b.totalPages;)this.turn("removePage",b.totalPages);else{if(1>a||a>b.totalPages)throw q("The page "+a+" doesn't exist");b.pageObjs[a]&&(this.turn("stop"),g._removePageFromDOM.call(this,a),delete b.pageObjs[a]);g._movePages.call(this,a,-1);b.totalPages-=1;b.page>
+b.totalPages?(b.page=null,g._fitPage.call(this,b.totalPages)):(g._makeRange.call(this),this.turn("update"))}return this},_movePages:function(a,b){var c,d=this,e=this.data(),h="single"==e.display,f=function(a){var c=a+b,f=c%2,i=f?" odd ":" even ";e.pageObjs[a]&&(e.pageObjs[c]=e.pageObjs[a].removeClass("p"+a+" odd even").addClass("p"+c+i));e.pagePlace[a]&&e.pageWrap[a]&&(e.pagePlace[c]=c,e.pageWrap[c]=e.pageObjs[c].hasClass("fixed")?e.pageWrap[a].attr("page",c):e.pageWrap[a].css(g._pageSize.call(d,
+c,!0)).attr("page",c),e.pages[a]&&(e.pages[c]=e.pages[a].flip("options",{page:c,next:h||f?c+1:c-1})),b&&(delete e.pages[a],delete e.pagePlace[a],delete e.pageZoom[a],delete e.pageObjs[a],delete e.pageWrap[a]))};if(0<b)for(c=e.totalPages;c>=a;c--)f(c);else for(c=a;c<=e.totalPages;c++)f(c)},display:function(a){var b=this.data(),c=b.display;if(void 0===a)return c;if(-1==f.inArray(a,V))throw q('"'+a+'" is not a value for display');switch(a){case "single":b.pageObjs[0]||(this.turn("stop").css({overflow:"hidden"}),
+b.pageObjs[0]=f("<div />",{"class":"page p-temporal"}).css({width:this.width(),height:this.height()}).appendTo(this));this.addClass("shadow");break;case "double":b.pageObjs[0]&&(this.turn("stop").css({overflow:""}),b.pageObjs[0].remove(),delete b.pageObjs[0]),this.removeClass("shadow")}b.display=a;c&&(a=this.turn("size"),g._movePages.call(this,1,0),this.turn("size",a.width,a.height).turn("update"));return this},direction:function(a){var b=this.data();if(void 0===a)return b.direction;a=a.toLowerCase();
+if(-1==f.inArray(a,W))throw q('"'+a+'" is not a value for direction');"rtl"==a&&f(this).attr("dir","ltr").css({direction:"ltr"});b.direction=a;b.done&&this.turn("size",f(this).width(),f(this).height());return this},animating:function(){return 0<this.data().pageMv.length},corner:function(){var a,b,c=this.data();for(b in c.pages)if(n(b,c.pages)&&(a=c.pages[b].flip("corner")))return a;return!1},data:function(){return this.data()},disable:function(a){var b,c=this.data(),d=this.turn("view");c.disabled=
+void 0===a||!0===a;for(b in c.pages)n(b,c.pages)&&c.pages[b].flip("disable",c.disabled?!0:-1==f.inArray(parseInt(b,10),d));return this},disabled:function(a){return void 0===a?!0===this.data().disabled:this.turn("disable",a)},size:function(a,b){if(void 0===a||void 0===b)return{width:this.width(),height:this.height()};this.turn("stop");var c,d,e=this.data();d="double"==e.display?a/2:a;this.css({width:a,height:b});e.pageObjs[0]&&e.pageObjs[0].css({width:d,height:b});for(c in e.pageWrap)n(c,e.pageWrap)&&
+(d=g._pageSize.call(this,c,!0),e.pageObjs[c].css({width:d.width,height:d.height}),e.pageWrap[c].css(d),e.pages[c]&&e.pages[c].css({width:d.width,height:d.height}));this.turn("resize");return this},resize:function(){var a,b=this.data();b.pages[0]&&(b.pageWrap[0].css({left:-this.width()}),b.pages[0].flip("resize",!0));for(a=1;a<=b.totalPages;a++)b.pages[a]&&b.pages[a].flip("resize",!0);g._updateShadow.call(this);b.opts.autoCenter&&this.turn("center")},_removeMv:function(a){var b,c=this.data();for(b=
+0;b<c.pageMv.length;b++)if(c.pageMv[b]==a)return c.pageMv.splice(b,1),!0;return!1},_addMv:function(a){var b=this.data();g._removeMv.call(this,a);b.pageMv.push(a)},_view:function(a){var b=this.data(),a=a||b.page;return"double"==b.display?a%2?[a-1,a]:[a,a+1]:[a]},view:function(a){var b=this.data(),a=g._view.call(this,a);return"double"==b.display?[0<a[0]?a[0]:0,a[1]<=b.totalPages?a[1]:0]:[0<a[0]&&a[0]<=b.totalPages?a[0]:0]},stop:function(a,b){if(this.turn("animating")){var c,d,e,h=this.data();h.tpage&&
+(h.page=h.tpage,delete h.tpage);for(c=0;c<h.pageMv.length;c++)h.pageMv[c]&&h.pageMv[c]!==a&&(e=h.pages[h.pageMv[c]],d=e.data().f.opts,e.flip("hideFoldedPage",b),b||i._moveFoldingPage.call(e,!1),d.force&&(d.next=0===d.page%2?d.page-1:d.page+1,delete d.force))}this.turn("update");return this},pages:function(a){var b=this.data();if(a){if(a<b.totalPages)for(var c=b.totalPages;c>a;c--)this.turn("removePage",c);b.totalPages=a;g._fitPage.call(this,b.page);return this}return b.totalPages},_missing:function(a){var b=
+this.data();if(!(1>b.totalPages)){for(var c=this.turn("range",a),d=[],a=c[0];a<=c[1];a++)b.pageObjs[a]||d.push(a);0<d.length&&this.trigger("missing",[d])}},_fitPage:function(a){var b=this.data(),c=this.turn("view",a);g._missing.call(this,a);if(b.pageObjs[a]){b.page=a;this.turn("stop");for(var d=0;d<c.length;d++)c[d]&&b.pageZoom[c[d]]!=b.zoom&&(this.trigger("zoomed",[c[d],c,b.pageZoom[c[d]],b.zoom]),b.pageZoom[c[d]]=b.zoom);g._removeFromDOM.call(this);g._makeRange.call(this);g._updateShadow.call(this);
+this.trigger("turned",[a,c]);this.turn("update");b.opts.autoCenter&&this.turn("center")}},_turnPage:function(a){var b,c,d=this.data(),e=d.pagePlace[a],h=this.turn("view"),i=this.turn("view",a);if(d.page!=a){var j=d.page;if("prevented"==t("turning",this,[a,i])){j==d.page&&-1!=f.inArray(e,d.pageMv)&&d.pages[e].flip("hideFoldedPage",!0);return}-1!=f.inArray(1,i)&&this.trigger("first");-1!=f.inArray(d.totalPages,i)&&this.trigger("last")}"single"==d.display?(b=h[0],c=i[0]):h[1]&&a>h[1]?(b=h[1],c=i[0]):
+h[0]&&a<h[0]&&(b=h[0],c=i[1]);e=d.opts.turnCorners.split(",");h=d.pages[b].data().f;i=h.opts;j=h.point;g._missing.call(this,a);d.pageObjs[a]&&(this.turn("stop"),d.page=a,g._makeRange.call(this),d.tpage=c,i.next!=c&&(i.next=c,i.force=!0),this.turn("update"),h.point=j,"hard"==h.effect?"ltr"==d.direction?d.pages[b].flip("turnPage",a>b?"r":"l"):d.pages[b].flip("turnPage",a>b?"l":"r"):"ltr"==d.direction?d.pages[b].flip("turnPage",e[a>b?1:0]):d.pages[b].flip("turnPage",e[a>b?0:1]))},page:function(a){var b=
+this.data();if(void 0===a)return b.page;if(!b.disabled&&!b.destroying){a=parseInt(a,10);if(0<a&&a<=b.totalPages)return a!=b.page&&(!b.done||-1!=f.inArray(a,this.turn("view"))?g._fitPage.call(this,a):g._turnPage.call(this,a)),this;throw q("The page "+a+" does not exist");}},next:function(){return this.turn("page",Math.min(this.data().totalPages,g._view.call(this,this.data().page).pop()+1))},previous:function(){return this.turn("page",Math.max(1,g._view.call(this,this.data().page).shift()-1))},peel:function(a,
+b){var c=this.data(),d=this.turn("view"),b=void 0===b?!0:!0===b;!1===a?this.turn("stop",null,b):"single"==c.display?c.pages[c.page].flip("peel",a,b):(d="ltr"==c.direction?-1!=a.indexOf("l")?d[0]:d[1]:-1!=a.indexOf("l")?d[1]:d[0],c.pages[d]&&c.pages[d].flip("peel",a,b));return this},_addMotionPage:function(){var a=f(this).data().f.opts,b=a.turn;b.data();g._addMv.call(b,a.page)},_eventStart:function(a,b,c){var d=b.turn.data(),e=d.pageZoom[b.page];a.isDefaultPrevented()||(e&&e!=d.zoom&&(b.turn.trigger("zoomed",
+[b.page,b.turn.turn("view",b.page),e,d.zoom]),d.pageZoom[b.page]=d.zoom),"single"==d.display&&c&&("l"==c.charAt(1)&&"ltr"==d.direction||"r"==c.charAt(1)&&"rtl"==d.direction?(b.next=b.next<b.page?b.next:b.page-1,b.force=!0):b.next=b.next>b.page?b.next:b.page+1),g._addMotionPage.call(a.target));g._updateShadow.call(b.turn)},_eventEnd:function(a,b,c){f(a.target).data();var a=b.turn,d=a.data();if(c){if(c=d.tpage||d.page,c==b.next||c==b.page)delete d.tpage,g._fitPage.call(a,c||b.next,!0)}else g._removeMv.call(a,
+b.page),g._updateShadow.call(a),a.turn("update")},_eventPressed:function(a){var a=f(a.target).data().f,b=a.opts.turn;b.data().mouseAction=!0;b.turn("update");return a.time=(new Date).getTime()},_eventReleased:function(a,b){var c;c=f(a.target);var d=c.data().f,e=d.opts.turn,h=e.data();c="single"==h.display?"br"==b.corner||"tr"==b.corner?b.x<c.width()/2:b.x>c.width()/2:0>b.x||b.x>c.width();if(200>(new Date).getTime()-d.time||c)a.preventDefault(),g._turnPage.call(e,d.opts.next);h.mouseAction=!1},_flip:function(a){a.stopPropagation();
+a=f(a.target).data().f.opts;a.turn.trigger("turn",[a.next]);a.turn.data().opts.autoCenter&&a.turn.turn("center",a.next)},_touchStart:function(){var a=this.data(),b;for(b in a.pages)if(n(b,a.pages)&&!1===i._eventStart.apply(a.pages[b],arguments))return!1},_touchMove:function(){var a=this.data(),b;for(b in a.pages)n(b,a.pages)&&i._eventMove.apply(a.pages[b],arguments)},_touchEnd:function(){var a=this.data(),b;for(b in a.pages)n(b,a.pages)&&i._eventEnd.apply(a.pages[b],arguments)},calculateZ:function(a){var b,
+c,d,e,h=this,f=this.data();b=this.turn("view");var i=b[0]||b[1],g=a.length-1,j={pageZ:{},partZ:{},pageV:{}},k=function(a){a=h.turn("view",a);a[0]&&(j.pageV[a[0]]=!0);a[1]&&(j.pageV[a[1]]=!0)};for(b=0;b<=g;b++)c=a[b],d=f.pages[c].data().f.opts.next,e=f.pagePlace[c],k(c),k(d),c=f.pagePlace[d]==d?d:c,j.pageZ[c]=f.totalPages-Math.abs(i-c),j.partZ[e]=2*f.totalPages-g+b;return j},update:function(){var a,b=this.data();if(this.turn("animating")&&0!==b.pageMv[0]){var c,d=this.turn("calculateZ",b.pageMv),e=
+this.turn("corner"),h=this.turn("view"),i=this.turn("view",b.tpage);for(a in b.pageWrap)if(n(a,b.pageWrap)&&(c=b.pageObjs[a].hasClass("fixed"),b.pageWrap[a].css({display:d.pageV[a]||c?"":"none",zIndex:(b.pageObjs[a].hasClass("hard")?d.partZ[a]:d.pageZ[a])||(c?-1:0)}),c=b.pages[a]))c.flip("z",d.partZ[a]||null),d.pageV[a]&&c.flip("resize"),b.tpage?c.flip("hover",!1).flip("disable",-1==f.inArray(parseInt(a,10),b.pageMv)&&a!=i[0]&&a!=i[1]):c.flip("hover",!1===e).flip("disable",a!=h[0]&&a!=h[1])}else for(a in b.pageWrap)n(a,
+b.pageWrap)&&(d=g._setPageLoc.call(this,a),b.pages[a]&&b.pages[a].flip("disable",b.disabled||1!=d).flip("hover",!0).flip("z",null));return this},_updateShadow:function(){var a,b,c=this.data(),d=this.width(),e=this.height(),h="single"==c.display?d:d/2;a=this.turn("view");c.shadow||(c.shadow=f("<div />",{"class":"shadow",css:l(0,0,0).css}).appendTo(this));for(var i=0;i<c.pageMv.length&&a[0]&&a[1];i++)a=this.turn("view",c.pages[c.pageMv[i]].data().f.opts.next),b=this.turn("view",c.pageMv[i]),a[0]=a[0]&&
+b[0],a[1]=a[1]&&b[1];switch(a[0]?a[1]?3:"ltr"==c.direction?2:1:"ltr"==c.direction?1:2){case 1:c.shadow.css({width:h,height:e,top:0,left:h});break;case 2:c.shadow.css({width:h,height:e,top:0,left:0});break;case 3:c.shadow.css({width:d,height:e,top:0,left:0})}},_setPageLoc:function(a){var b=this.data(),c=this.turn("view"),d=0;if(a==c[0]||a==c[1])d=1;else if("single"==b.display&&a==c[0]+1||"double"==b.display&&a==c[0]-2||a==c[1]+2)d=2;if(!this.turn("animating"))switch(d){case 1:b.pageWrap[a].css({zIndex:b.totalPages,
+display:""});break;case 2:b.pageWrap[a].css({zIndex:b.totalPages-1,display:""});break;case 0:b.pageWrap[a].css({zIndex:0,display:b.pageObjs[a].hasClass("fixed")?"":"none"})}return d},options:function(a){if(void 0===a)return this.data().opts;var b=this.data();f.extend(b.opts,a);a.pages&&this.turn("pages",a.pages);a.page&&this.turn("page",a.page);a.display&&this.turn("display",a.display);a.direction&&this.turn("direction",a.direction);a.width&&a.height&&this.turn("size",a.width,a.height);if(a.when)for(var c in a.when)n(c,
+a.when)&&this.unbind(c).bind(c,a.when[c]);return this},version:function(){return"4.1.0"}},i={init:function(a){this.data({f:{disabled:!1,hover:!1,effect:this.hasClass("hard")?"hard":"sheet"}});this.flip("options",a);i._addPageWrapper.call(this);return this},setData:function(a){var b=this.data();b.f=f.extend(b.f,a);return this},options:function(a){var b=this.data().f;return a?(i.setData.call(this,{opts:f.extend({},b.opts||Y,a)}),this):b.opts},z:function(a){var b=this.data().f;b.opts["z-index"]=a;b.fwrapper&&
+b.fwrapper.css({zIndex:a||parseInt(b.parent.css("z-index"),10)||0});return this},_cAllowed:function(){var a=this.data().f,b=a.opts.page,c=a.opts.turn.data(),d=b%2;return"hard"==a.effect?"ltr"==c.direction?[d?"r":"l"]:[d?"l":"r"]:"single"==c.display?1==b?"ltr"==c.direction?p.forward:p.backward:b==c.totalPages?"ltr"==c.direction?p.backward:p.forward:p.all:"ltr"==c.direction?p[d?"forward":"backward"]:p[d?"backward":"forward"]},_cornerActivated:function(a){var b=this.data().f,c=this.width(),d=this.height(),
+a={x:a.x,y:a.y,corner:""},e=b.opts.cornerSize;if(0>=a.x||0>=a.y||a.x>=c||a.y>=d)return!1;var h=i._cAllowed.call(this);switch(b.effect){case "hard":if(a.x>c-e)a.corner="r";else if(a.x<e)a.corner="l";else return!1;break;case "sheet":if(a.y<e)a.corner+="t";else if(a.y>=d-e)a.corner+="b";else return!1;if(a.x<=e)a.corner+="l";else if(a.x>=c-e)a.corner+="r";else return!1}return!a.corner||-1==f.inArray(a.corner,h)?!1:a},_isIArea:function(a){var b=this.data().f.parent.offset(),a=u&&a.originalEvent?a.originalEvent.touches[0]:
+a;return i._cornerActivated.call(this,{x:a.pageX-b.left,y:a.pageY-b.top})},_c:function(a,b){b=b||0;switch(a){case "tl":return j(b,b);case "tr":return j(this.width()-b,b);case "bl":return j(b,this.height()-b);case "br":return j(this.width()-b,this.height()-b);case "l":return j(b,0);case "r":return j(this.width()-b,0)}},_c2:function(a){switch(a){case "tl":return j(2*this.width(),0);case "tr":return j(-this.width(),0);case "bl":return j(2*this.width(),this.height());case "br":return j(-this.width(),
+this.height());case "l":return j(2*this.width(),0);case "r":return j(-this.width(),0)}},_foldingPage:function(){var a=this.data().f;if(a){var b=a.opts;if(b.turn)return a=b.turn.data(),"single"==a.display?1<b.next||1<b.page?a.pageObjs[0]:null:a.pageObjs[b.next]}},_backGradient:function(){var a=this.data().f,b=a.opts.turn.data();if((b=b.opts.gradients&&("single"==b.display||2!=a.opts.page&&a.opts.page!=b.totalPages-1))&&!a.bshadow)a.bshadow=f("<div/>",l(0,0,1)).css({position:"",width:this.width(),height:this.height()}).appendTo(a.parent);
+return b},type:function(){return this.data().f.effect},resize:function(a){var b=this.data().f,c=b.opts.turn.data(),d=this.width(),e=this.height();switch(b.effect){case "hard":a&&(b.wrapper.css({width:d,height:e}),b.fpage.css({width:d,height:e}),c.opts.gradients&&(b.ashadow.css({width:d,height:e}),b.bshadow.css({width:d,height:e})));break;case "sheet":a&&(a=Math.round(Math.sqrt(Math.pow(d,2)+Math.pow(e,2))),b.wrapper.css({width:a,height:a}),b.fwrapper.css({width:a,height:a}).children(":first-child").css({width:d,
+height:e}),b.fpage.css({width:d,height:e}),c.opts.gradients&&b.ashadow.css({width:d,height:e}),i._backGradient.call(this)&&b.bshadow.css({width:d,height:e})),b.parent.is(":visible")&&(c=D(b.parent[0]),b.fwrapper.css({top:c.top,left:c.left}),c=D(b.opts.turn[0]),b.fparent.css({top:-c.top,left:-c.left})),this.flip("z",b.opts["z-index"])}},_addPageWrapper:function(){var a=this.data().f,b=a.opts.turn.data(),c=this.parent();a.parent=c;if(!a.wrapper)switch(a.effect){case "hard":var d={};d[w+"transform-style"]=
+"preserve-3d";d[w+"backface-visibility"]="hidden";a.wrapper=f("<div/>",l(0,0,2)).css(d).appendTo(c).prepend(this);a.fpage=f("<div/>",l(0,0,1)).css(d).appendTo(c);b.opts.gradients&&(a.ashadow=f("<div/>",l(0,0,0)).hide().appendTo(c),a.bshadow=f("<div/>",l(0,0,0)));break;case "sheet":var d=this.width(),e=this.height();Math.round(Math.sqrt(Math.pow(d,2)+Math.pow(e,2)));a.fparent=a.opts.turn.data().fparent;a.fparent||(d=f("<div/>",{css:{"pointer-events":"none"}}).hide(),d.data().flips=0,d.css(l(0,0,"auto",
+"visible").css).appendTo(a.opts.turn),a.opts.turn.data().fparent=d,a.fparent=d);this.css({position:"absolute",top:0,left:0,bottom:"auto",right:"auto"});a.wrapper=f("<div/>",l(0,0,this.css("z-index"))).appendTo(c).prepend(this);a.fwrapper=f("<div/>",l(c.offset().top,c.offset().left)).hide().appendTo(a.fparent);a.fpage=f("<div/>",l(0,0,0,"visible")).css({cursor:"default"}).appendTo(a.fwrapper);b.opts.gradients&&(a.ashadow=f("<div/>",l(0,0,1)).appendTo(a.fpage));i.setData.call(this,a)}i.resize.call(this,
+!0)},_fold:function(a){var b=this.data().f,c=b.opts.turn.data(),d=i._c.call(this,a.corner),e=this.width(),h=this.height();switch(b.effect){case "hard":a.x="l"==a.corner?Math.min(Math.max(a.x,0),2*e):Math.max(Math.min(a.x,e),-e);var f,g,s,x,k,n=c.totalPages,l=b.opts["z-index"]||n,q={overflow:"visible"},p=d.x?(d.x-a.x)/e:a.x/e,r=90*p,t=90>r;switch(a.corner){case "l":x="0% 50%";k="100% 50%";t?(f=0,g=0<b.opts.next-1,s=1):(f="100%",g=b.opts.page+1<n,s=0);break;case "r":x="100% 50%",k="0% 50%",r=-r,e=-e,
+t?(f=0,g=b.opts.next+1<n,s=0):(f="-100%",g=1!=b.opts.page,s=1)}q[w+"perspective-origin"]=k;b.wrapper.transform("rotateY("+r+"deg)translate3d(0px, 0px, "+(this.attr("depth")||0)+"px)",k);b.fpage.transform("translateX("+e+"px) rotateY("+(180+r)+"deg)",x);b.parent.css(q);t?(p=-p+1,b.wrapper.css({zIndex:l+1}),b.fpage.css({zIndex:l})):(p-=1,b.wrapper.css({zIndex:l}),b.fpage.css({zIndex:l+1}));c.opts.gradients&&(g?b.ashadow.css({display:"",left:f,backgroundColor:"rgba(0,0,0,"+0.5*p+")"}).transform("rotateY(0deg)"):
+b.ashadow.hide(),b.bshadow.css({opacity:-p+1}),t?b.bshadow.parent()[0]!=b.wrapper[0]&&b.bshadow.appendTo(b.wrapper):b.bshadow.parent()[0]!=b.fpage[0]&&b.bshadow.appendTo(b.fpage),P(b.bshadow,j(100*s,0),j(100*(-s+1),0),[[0,"rgba(0,0,0,0.3)"],[1,"rgba(0,0,0,0)"]],2));break;case "sheet":var u=this,H=0,z,A,B,M,y,N,D,v=j(0,0),Q=j(0,0),m=j(0,0),J=i._foldingPage.call(this);Math.tan(0);var O=c.opts.acceleration,R=b.wrapper.height(),E="t"==a.corner.substr(0,1),C="l"==a.corner.substr(1,1),I=function(){var b=
+j(0,0),f=j(0,0);b.x=d.x?d.x-a.x:a.x;b.y=U?d.y?d.y-a.y:a.y:0;f.x=C?e-b.x/2:a.x+b.x/2;f.y=b.y/2;var g=L-Math.atan2(b.y,b.x),k=g-Math.atan2(f.y,f.x),k=Math.max(0,Math.sin(k)*Math.sqrt(Math.pow(f.x,2)+Math.pow(f.y,2)));H=180*(g/K);m=j(k*Math.sin(g),k*Math.cos(g));if(g>L&&(m.x+=Math.abs(m.y*b.y/b.x),m.y=0,Math.round(m.x*Math.tan(K-g))<h))return a.y=Math.sqrt(Math.pow(h,2)+2*f.x*b.x),E&&(a.y=h-a.y),I();g>L&&(b=K-g,f=R-h/Math.sin(b),v=j(Math.round(f*Math.cos(b)),Math.round(f*Math.sin(b))),C&&(v.x=-v.x),
+E&&(v.y=-v.y));z=Math.round(m.y/Math.tan(g)+m.x);b=e-z;f=b*Math.cos(2*g);k=b*Math.sin(2*g);Q=j(Math.round(C?b-f:z+f),Math.round(E?k:h-k));c.opts.gradients&&(y=b*Math.sin(g),b=i._c2.call(u,a.corner),b=Math.sqrt(Math.pow(b.x-a.x,2)+Math.pow(b.y-a.y,2))/e,D=Math.sin(L*(1<b?2-b:b)),N=Math.min(b,1),M=100<y?(y-100)/y:0,A=j(100*(y*Math.sin(g)/e),100*(y*Math.cos(g)/h)),i._backGradient.call(u)&&(B=j(100*(1.2*y*Math.sin(g)/e),100*(1.2*y*Math.cos(g)/h)),C||(B.x=100-B.x),E||(B.y=100-B.y)));m.x=Math.round(m.x);
+m.y=Math.round(m.y);return!0};f=function(a,d,f,g){var k=["0","auto"],m=(e-R)*f[0]/100,l=(h-R)*f[1]/100,d={left:k[d[0]],top:k[d[1]],right:k[d[2]],bottom:k[d[3]]},k={},n=90!=g&&-90!=g?C?-1:1:0,s=f[0]+"% "+f[1]+"%";u.css(d).transform(G(g)+F(a.x+n,a.y,O),s);b.fpage.css(d).transform(G(g)+F(a.x+Q.x-v.x-e*f[0]/100,a.y+Q.y-v.y-h*f[1]/100,O)+G((180/g-2)*g),s);b.wrapper.transform(F(-a.x+m-n,-a.y+l,O)+G(-g),s);b.fwrapper.transform(F(-a.x+v.x+m,-a.y+v.y+l,O)+G(-g),s);c.opts.gradients&&(f[0]&&(A.x=100-A.x),f[1]&&
+(A.y=100-A.y),k["box-shadow"]="0 0 20px rgba(0,0,0,"+0.5*D+")",J.css(k),P(b.ashadow,j(C?100:0,E?0:100),j(A.x,A.y),[[M,"rgba(0,0,0,0)"],[0.8*(1-M)+M,"rgba(0,0,0,"+0.2*N+")"],[1,"rgba(255,255,255,"+0.2*N+")"]],3,0),i._backGradient.call(u)&&P(b.bshadow,j(C?0:100,E?0:100),j(B.x,B.y),[[0.6,"rgba(0,0,0,0)"],[0.8,"rgba(0,0,0,"+0.3*N+")"],[1,"rgba(0,0,0,0)"]],3))};switch(a.corner){case "tl":a.x=Math.max(a.x,1);I();f(m,[1,0,0,1],[100,0],H);break;case "tr":a.x=Math.min(a.x,e-1);I();f(j(-m.x,m.y),[0,0,0,1],
+[0,0],-H);break;case "bl":a.x=Math.max(a.x,1);I();f(j(m.x,-m.y),[1,1,0,0],[100,100],-H);break;case "br":a.x=Math.min(a.x,e-1),I(),f(j(-m.x,-m.y),[0,1,1,0],[0,100],H)}}b.point=a},_moveFoldingPage:function(a){var b=this.data().f;if(b){var c=b.opts.turn,d=c.data(),e=d.pagePlace;a?(d=b.opts.next,e[d]!=b.opts.page&&(b.folding&&i._moveFoldingPage.call(this,!1),i._foldingPage.call(this).appendTo(b.fpage),e[d]=b.opts.page,b.folding=d),c.turn("update")):b.folding&&(d.pages[b.folding]?(c=d.pages[b.folding].data().f,
+d.pageObjs[b.folding].appendTo(c.wrapper)):d.pageWrap[b.folding]&&d.pageObjs[b.folding].appendTo(d.pageWrap[b.folding]),b.folding in e&&(e[b.folding]=b.folding),delete b.folding)}},_showFoldedPage:function(a,b){var c=i._foldingPage.call(this),d=this.data(),e=d.f,f=e.visible;if(c){if(!f||!e.point||e.point.corner!=a.corner)if(c="hover"==e.status||"peel"==e.status||e.opts.turn.data().mouseAction?a.corner:null,f=!1,"prevented"==t("start",this,[e.opts,c]))return!1;if(b){var g=this,d=e.point&&e.point.corner==
+a.corner?e.point:i._c.call(this,a.corner,1);this.animatef({from:[d.x,d.y],to:[a.x,a.y],duration:500,frame:function(b){a.x=Math.round(b[0]);a.y=Math.round(b[1]);i._fold.call(g,a)}})}else i._fold.call(this,a),d.effect&&!d.effect.turning&&this.animatef(!1);if(!f)switch(e.effect){case "hard":e.visible=!0;i._moveFoldingPage.call(this,!0);e.fpage.show();e.opts.shadows&&e.bshadow.show();break;case "sheet":e.visible=!0,e.fparent.show().data().flips++,i._moveFoldingPage.call(this,!0),e.fwrapper.show(),e.bshadow&&
+e.bshadow.show()}return!0}return!1},hide:function(){var a=this.data().f,b=a.opts.turn.data(),c=i._foldingPage.call(this);switch(a.effect){case "hard":b.opts.gradients&&(a.bshadowLoc=0,a.bshadow.remove(),a.ashadow.hide());a.wrapper.transform("");a.fpage.hide();break;case "sheet":0===--a.fparent.data().flips&&a.fparent.hide(),this.css({left:0,top:0,right:"auto",bottom:"auto"}).transform(""),a.wrapper.transform(""),a.fwrapper.hide(),a.bshadow&&a.bshadow.hide(),c.transform("")}a.visible=!1;return this},
+hideFoldedPage:function(a){var b=this.data().f;if(b.point){var c=this,d=b.point,e=function(){b.point=null;b.status="";c.flip("hide");c.trigger("end",[b.opts,!1])};if(a){var f=i._c.call(this,d.corner),a="t"==d.corner.substr(0,1)?Math.min(0,d.y-f.y)/2:Math.max(0,d.y-f.y)/2,g=j(d.x,d.y+a),l=j(f.x,f.y-a);this.animatef({from:0,to:1,frame:function(a){a=S(d,g,l,f,a);d.x=a.x;d.y=a.y;i._fold.call(c,d)},complete:e,duration:800,hiding:!0})}else this.animatef(!1),e()}},turnPage:function(a){var b=this,c=this.data().f,
+d=c.opts.turn.data(),a={corner:c.corner?c.corner.corner:a||i._cAllowed.call(this)[0]},e=c.point||i._c.call(this,a.corner,c.opts.turn?d.opts.elevation:0),f=i._c2.call(this,a.corner);this.trigger("flip").animatef({from:0,to:1,frame:function(c){c=S(e,e,f,f,c);a.x=c.x;a.y=c.y;i._showFoldedPage.call(b,a)},complete:function(){b.trigger("end",[c.opts,!0])},duration:d.opts.duration,turning:!0});c.corner=null},moving:function(){return"effect"in this.data()},isTurning:function(){return this.flip("moving")&&
+this.data().effect.turning},corner:function(){return this.data().f.corner},_eventStart:function(a){var b=this.data().f,c=b.opts.turn;if(!b.corner&&!b.disabled&&!this.flip("isTurning")&&b.opts.page==c.data().pagePlace[b.opts.page]){b.corner=i._isIArea.call(this,a);if(b.corner&&i._foldingPage.call(this))return this.trigger("pressed",[b.point]),i._showFoldedPage.call(this,b.corner),!1;b.corner=null}},_eventMove:function(a){var b=this.data().f;if(!b.disabled)if(a=u?a.originalEvent.touches:[a],b.corner){var c=
+b.parent.offset();b.corner.x=a[0].pageX-c.left;b.corner.y=a[0].pageY-c.top;i._showFoldedPage.call(this,b.corner)}else if(b.hover&&!this.data().effect&&this.is(":visible"))if(a=i._isIArea.call(this,a[0])){if("sheet"==b.effect&&2==a.corner.length||"hard"==b.effect)b.status="hover",b=i._c.call(this,a.corner,b.opts.cornerSize/2),a.x=b.x,a.y=b.y,i._showFoldedPage.call(this,a,!0)}else"hover"==b.status&&(b.status="",i.hideFoldedPage.call(this,!0))},_eventEnd:function(){var a=this.data().f,b=a.corner;!a.disabled&&
+b&&"prevented"!=t("released",this,[a.point||b])&&i.hideFoldedPage.call(this,!0);a.corner=null},disable:function(a){i.setData.call(this,{disabled:a});return this},hover:function(a){i.setData.call(this,{hover:a});return this},peel:function(a,b){var c=this.data().f;if(a){if(-1==f.inArray(a,p.all))throw q("Corner "+a+" is not permitted");if(-1!=f.inArray(a,i._cAllowed.call(this))){var d=i._c.call(this,a,c.opts.cornerSize/2);c.status="peel";i._showFoldedPage.call(this,{corner:a,x:d.x,y:d.y},b)}}else c.status=
+"",i.hideFoldedPage.call(this,b);return this}};window.requestAnim=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)};f.extend(f.fn,{flip:function(){return J(f(this[0]),i,arguments)},turn:function(){return J(f(this[0]),g,arguments)},transform:function(a,b){var c={};b&&(c[w+"transform-origin"]=b);c[w+"transform"]=a;return this.css(c)},animatef:function(a){var b=
+this.data();b.effect&&b.effect.stop();if(a){a.to.length||(a.to=[a.to]);a.from.length||(a.from=[a.from]);for(var c=[],d=a.to.length,e=!0,g=this,i=(new Date).getTime(),j=function(){if(b.effect&&e){for(var f=[],k=Math.min(a.duration,(new Date).getTime()-i),l=0;l<d;l++)f.push(b.effect.easing(1,k,a.from[l],c[l],a.duration));a.frame(1==d?f[0]:f);k==a.duration?(delete b.effect,g.data(b),a.complete&&a.complete()):window.requestAnim(j)}},l=0;l<d;l++)c.push(a.to[l]-a.from[l]);b.effect=f.extend({stop:function(){e=
+!1},easing:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c}},a);this.data(b);j()}else delete b.effect}});f.isTouch=u;f.mouseEvents=r;f.cssPrefix=T;f.cssTransitionEnd=function(){var a,b=document.createElement("fakeelement"),c={transition:"transitionend",OTransition:"oTransitionEnd",MSTransition:"transitionend",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(a in c)if(void 0!==b.style[a])return c[a]};f.findPos=D})(jQuery);

+ 84 - 0
src/views/courseware-list/component/book/index.module.less

@@ -0,0 +1,84 @@
+.book {
+    position: fixed;
+    inset: 0;
+    z-index: 100;
+    padding-top: 10vh;
+    .back{
+        position: absolute;
+        left: 41px;
+        top: 24px;
+    }
+    &.bookHide{
+        visibility: hidden;
+        pointer-events: none;
+        opacity: 0;
+    }
+    :global {
+        .bookWrap{
+            margin: 0 auto;
+        }
+        .animated {
+            transition: margin-left 0.2s ease-in-out;
+        }
+        #flipbook {
+            // margin: 0 auto;
+        }
+
+        .page {
+            background: white;
+        }
+
+        .shadow {
+            box-shadow: 0 0 20px 0 rgba(0, 0, 0, .4);
+        }
+
+        .even .gradient {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            background-image: url(./pics/right-border.png);
+            background-position: right top;
+            background-repeat: repeat-y;
+        }
+
+        .odd .gradient {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            background-image: url(./pics/left-border.png);
+            background-position: left top;
+            background-repeat: repeat-y;
+        }
+
+        .page-wrapper {
+            perspective: 2000px;
+        }
+    }
+}
+.wrap{
+    position: relative;
+    padding: 41px 24px;
+    .item{
+        font-size: 15px;
+        font-weight: 600;
+        color: #333;
+        line-height: 20px;
+        padding: 12px 0;
+    }
+    .des{
+        display: flex;
+        padding-left: 20px;
+        justify-content: space-between;
+        align-items: center;
+        font-size: 14px;
+        line-height: 19px;
+    }
+    .icon{
+        width: 22px;
+        height: 22px;
+    }
+}

+ 222 - 0
src/views/courseware-list/component/book/index.tsx

@@ -0,0 +1,222 @@
+import {
+  PropType,
+  defineComponent,
+  nextTick,
+  onMounted,
+  reactive,
+  watch
+} from 'vue';
+import styles from './index.module.less';
+import icon_back from '../../image/icon_back.svg';
+import icon_play from '../../image/icon_play.svg';
+import { useRouter } from 'vue-router';
+
+export default defineComponent({
+  name: 'the-book',
+  props: {
+    bookData: {
+      type: Object as PropType<any>,
+      default: () => ({})
+    },
+    show: {
+      type: Boolean,
+      default: false
+    },
+    rect: {
+      type: Object as PropType<DOMRect>,
+      default: () => ({})
+    }
+  },
+  emits: ['close'],
+  setup(props, { emit }) {
+    const router = useRouter();
+    const data = reactive({
+      show: false,
+      width: 0,
+      height: 0,
+      transform: '',
+      list: [] as any[][]
+    });
+    const handleCreate = (key: string, url: string) => {
+      return new Promise((resolve, reject) => {
+        const _s = document.head.querySelector(`script[data-key="${key}"]`);
+        if (!_s) {
+          const s = document.createElement('script');
+          s.setAttribute('data-key', key);
+          s.src = url;
+          s.onload = async () => {
+            console.log(key + ' 加载完成');
+            resolve(1);
+          };
+          document.head.appendChild(s);
+        }
+      });
+    };
+    const init = async () => {
+      await handleCreate('jquery', '/book/jquery.min.1.7.js');
+      await handleCreate('turn', '/book/turn.js');
+      console.log('初始化完成');
+    };
+    let book: any = null;
+    let timer: any = null;
+    const handleBook = () => {
+      book = (window as any).$('#flipbook');
+      const height = document.body.clientHeight * 0.8;
+
+      data.height = height;
+      data.width = height * (210 / 297) * 2;
+      book.turn({
+        autoCenter: true,
+        duration: 1000,
+        acceleration: true, // 是否启动硬件加速 如果为触摸设备必须为true
+        // pages: 11, // 页码总数
+        elevation: 50, // 转换期间页面的高度
+        width: data.width, // 宽度 单位 px
+        height: data.height, // 高度 单位 px
+        gradients: true // 是否显示翻页阴影效果
+        // display: 'single', //设置单页还是双页
+      });
+    };
+    const getRect = () => {
+      const bookWrap = document.querySelector(
+        '.bookWrap'
+      ) as unknown as HTMLElement;
+      if (bookWrap) {
+        const rect = bookWrap.getBoundingClientRect();
+        const xScale = props.rect.width / (rect.width / 2);
+        const yScale = props.rect.height / rect.height;
+        const left =
+          (((rect.width / 2) * (xScale - 1)) / 2 +
+            props.rect.x -
+            rect.x -
+            rect.width / 4) /
+          xScale;
+        const top =
+          ((rect.height * (yScale - 1)) / 2 + props.rect.y - rect.y) / yScale;
+        const transform = `scale3d(${xScale}, ${yScale}, 1) translate(${left}px, ${top}px)`;
+        bookWrap.style.transform = data.transform = transform;
+        requestAnimationFrame(() => {
+          bookWrap.style.transition = 'transform 1s';
+          bookWrap.style.transform = '';
+          data.show = true;
+          timer = setTimeout(() => {
+            book.turn('page', 2);
+          }, 500);
+        });
+      }
+    };
+    const handleClose = () => {
+      clearTimeout(timer);
+      const bookWrap = document.querySelector(
+        '.bookWrap'
+      ) as unknown as HTMLElement;
+      book.turn('page', 1);
+      if (bookWrap) {
+        bookWrap.style.transform = data.transform;
+      }
+      emit('close');
+      setTimeout(() => {
+        bookWrap.style.transition = '';
+        bookWrap.style.transform = '';
+        data.show = false;
+        data.list = [];
+      }, 1000);
+    };
+    onMounted(async () => {
+      await init();
+      //   handleBook();
+    });
+    const getList = () => {
+      if (!props.bookData?.lessonList) return;
+      const list = [];
+      let listItem = [] as any[];
+      for (let i = 0; i < props.bookData.lessonList.length; i++) {
+        const item = props.bookData.lessonList[i];
+        if (listItem.length < 5) {
+          listItem.push({ name: item.name });
+        } else {
+          listItem = [{ name: item.name }];
+        }
+        for (let j = 0; j < item.knowledgeList.length; j++) {
+          if (listItem.length < 5) {
+            listItem.push(item.knowledgeList[j]);
+          } else {
+            list.push(listItem);
+            listItem = [item.knowledgeList[j]];
+          }
+        }
+      }
+      if (listItem.length) {
+        list.push(listItem);
+      }
+      data.list = list;
+    };
+    watch(
+      () => props.show,
+      () => {
+        if (props.show) {
+          getList();
+          nextTick(() => {
+            handleBook();
+            requestAnimationFrame(() => {
+              getRect();
+            });
+          });
+        }
+      }
+    );
+    return () => (
+      <div class={[styles.book, data.show ? '' : styles.bookHide]}>
+        <div class={styles.back} onClick={handleClose}>
+          <img src={icon_back} />
+        </div>
+        <div class="bookWrap" style={{ width: data.width + 'px' }}>
+          {!!data.list.length && (
+            <div id="flipbook" class="animated">
+              <div class="page">
+                <img
+                  style="width: 100%; height: 100%; object-fit: cover;"
+                  src={props.bookData.coverImg}
+                />
+              </div>
+              {data.list.map((list: any) => {
+                return (
+                  <div class="page">
+                    <div class="gradient"></div>
+                    <div class={styles.wrap}>
+                      {list.map((item: any) => {
+                        return (
+                          <div
+                            class={[styles.item, item.id && styles.des]}
+                            onClick={() => {
+                              if (item.id) {
+                                router.push({
+                                  path: '/courseware-play',
+                                  query: {
+                                    id: item.id,
+                                    name: item.name
+                                  }
+                                });
+                              }
+                            }}>
+                            <div class={styles.name}>{item.name}</div>
+                            {item.id ? (
+                              <img class={styles.icon} src={icon_play} />
+                            ) : null}
+                          </div>
+                        );
+                      })}
+                    </div>
+                  </div>
+                );
+              })}
+              <div class="page">
+                <div class="gradient"></div>
+              </div>
+            </div>
+          )}
+        </div>
+      </div>
+    );
+  }
+});

BIN
src/views/courseware-list/component/book/pics/left-border.png


BIN
src/views/courseware-list/component/book/pics/loader.gif


BIN
src/views/courseware-list/component/book/pics/preview.jpg


BIN
src/views/courseware-list/component/book/pics/right-border.png


BIN
src/views/courseware-list/component/book/pics/tab-hover.png


BIN
src/views/courseware-list/component/book/pics/tab-off.png


BIN
src/views/courseware-list/component/book/pics/tab-on.png


+ 28 - 0
src/views/courseware-list/image/icon_play.svg

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <defs>
+        <linearGradient x1="-18.8072991%" y1="100%" x2="79.3329805%" y2="50%" id="linearGradient-1">
+            <stop stop-color="#5BECFF" offset="0%"></stop>
+            <stop stop-color="#259CFE" offset="100%"></stop>
+        </linearGradient>
+        <path d="M15.6029464,13.4596875 L10.1458929,16.8203571 C9.74282143,17.0685804 9.21482143,16.9430357 8.96657143,16.5399643 C8.88334767,16.4048171 8.83928571,16.2492166 8.83928571,16.0905 L8.83928571,7.9095 C8.83928571,7.43611607 9.22304464,7.05235714 9.69642857,7.05235714 C9.85514513,7.05235714 10.0107457,7.0964191 10.1458929,7.17964286 L15.6029464,10.5403125 C16.4091161,11.0367857 16.6601786,12.0927589 16.1637054,12.8989286 C16.023184,13.127108 15.8311258,13.3191661 15.6029464,13.4596875 L15.6029464,13.4596875 Z" id="path-2"></path>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="课件" transform="translate(-359.000000, -135.000000)" fill-rule="nonzero">
+            <g id="编组-6" transform="translate(86.000000, 76.000000)">
+                <g id="编组" transform="translate(33.000000, 0.000000)">
+                    <g id="编组-3" transform="translate(0.000000, 52.000000)">
+                        <g id="编组" transform="translate(240.000000, 7.000000)">
+                            <path d="M12,24 C5.37257143,24 0,18.6274286 0,12 C0,5.37257143 5.37257143,0 12,0 C18.6274286,0 24,5.37257143 24,12 C24,18.6274286 18.6274286,24 12,24 Z" id="路径" fill="#E0F2F7" opacity="0.597249"></path>
+                            <g id="形状">
+                                <use fill="#2DC7AA" xlink:href="#path-2"></use>
+                                <use fill="url(#linearGradient-1)" xlink:href="#path-2"></use>
+                            </g>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/views/courseware-list/image/wall-bookshelf.png


+ 24 - 8
src/views/courseware-list/index.module.less

@@ -9,10 +9,18 @@
 }
 
 .head {
+    position: relative;
     display: flex;
     align-items: center;
     justify-content: space-between;
     padding: 19px 23px 8px 41px;
+    transition: opacity .3s ease-in-out;
+
+    .back {
+        img {
+            display: block;
+        }
+    }
 
     .tabs {
         :global {
@@ -104,8 +112,9 @@
     overflow-y: hidden;
     overflow-x: auto;
     display: flex;
-
+    
     .wrap {
+        position: relative;
         display: flex;
         height: 100%;
         padding: 40px 63px 0;
@@ -119,7 +128,11 @@
     flex-direction: column;
     margin: 0 17px;
     flex-shrink: 0;
-
+    z-index: 1;
+    transition: all .3s .3s;
+    &.wrapItemHide{
+        // opacity: 0;
+    }
 
 
     .name {
@@ -148,7 +161,7 @@
     background-image: url('./image/icon_default.svg');
     background-repeat: no-repeat;
     background-position: center center;
-
+    
     &::after {
         content: '';
         position: absolute;
@@ -180,7 +193,7 @@
     }
 }
 
-.book{
+.book {
     position: fixed;
     top: 50%;
     left: 50%;
@@ -192,16 +205,19 @@
     visibility: hidden;
     pointer-events: none;
     border-radius: 8px;
-    box-shadow: 0 0 10px 0 rgba(0,0,0,.2);
-    .bookWrap{
+    box-shadow: 0 0 10px 0 rgba(0, 0, 0, .2);
+
+    .bookWrap {
         height: 60vh;
         overflow-y: auto;
-        ul{
+
+        ul {
             list-style: circle;
             padding: 10px 40px;
         }
     }
-    &.show{
+
+    &.show {
         visibility: visible;
         pointer-events: auto;
         transform: translate(-50%, -50%) scale(1);

+ 39 - 37
src/views/courseware-list/index.tsx

@@ -20,6 +20,7 @@ import { NImage } from 'naive-ui';
 import { state } from '@/state';
 import TheFavorite from '@/components/the-favorite';
 import { useRouter } from 'vue-router';
+import TheBook from './component/book';
 
 export const BOOK_DATA = {
   grades: [
@@ -73,7 +74,9 @@ export default defineComponent({
       favoriteList: [] as any[],
       tab: 'all',
       details: [] as any[],
-      showBook: false
+      bookData: {} as any,
+      showBook: false,
+      book: {} as DOMRect
     });
 
     const getList = async () => {
@@ -149,6 +152,7 @@ export default defineComponent({
       const res = await api_lessonCoursewareDetail(item.id);
       if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
         data.details = res.data.lessonList || [];
+        data.bookData = res.data;
         console.log('🚀 ~ data.details:', data.details);
       }
     };
@@ -159,43 +163,26 @@ export default defineComponent({
       ) as unknown as HTMLElement;
       if (!box) return;
       const rect = box.getBoundingClientRect();
-      const container = document.createElement('div');
-      console.log('🚀 ~ box:', box);
-      container.style.left = `${rect.x}px`;
-      container.style.top = `${rect.y}px`;
-      container.style.width = `${rect.width}px`;
-      container.style.height = `${rect.height}px`;
-      container.style.position = 'fixed';
-      container.style.zIndex = '9999';
-      container.appendChild(box.cloneNode(true));
-      document.body.appendChild(container);
-      setTimeout(() => {
-        container.style.transformOrigin = 'left';
-        container.style.left = `50vw`;
-        container.style.top = `25vh`;
-        container.style.transition = 'all 0.3s ease-in-out';
-        container.style.transform = 'scale(1.5)';
-        container.style.backfaceVisibility = 'hidden';
-        setTimeout(() => {
-          container.style.transform = 'scale(1.5) rotateY(180deg)';
-        }, 300);
-      }, 0);
+      data.book = rect;
     };
-    const handleOpen = (item: any) => {
-      getDetail(item);
-      data.showBook = true;
-      //   handleCreateContainer(item.id);
-      // postMessage({
-      //     api: 'openCourseware',
-      //     params: {
-      //     lessonCoursewareId: item.id
-      //     }
-      // });
+    const handleRender = (fn: any) => {
+      requestAnimationFrame(() => {
+        requestAnimationFrame(() => {
+          fn();
+        });
+      });
+    };
+    const handleOpen = async (item: any) => {
+      await getDetail(item);
+      handleCreateContainer(item.id);
+      handleRender(() => {
+        data.showBook = true;
+      });
     };
 
     return () => (
       <div class={styles.container}>
-        <div class={styles.head}>
+        <div class={styles.head} style={{ opacity: data.showBook ? 0 : '' }}>
           <div class={styles.back} onClick={goback}>
             <img src={icon_back} />
           </div>
@@ -226,7 +213,12 @@ export default defineComponent({
             {data.list.map((item, index) => {
               return (
                 <div
-                  class={styles.wrapItem}
+                  class={[
+                    styles.wrapItem,
+                    data.bookData.id === item.id && data.showBook
+                      ? styles.wrapItemHide
+                      : ''
+                  ]}
                   key={item.key}
                   onClick={() => handleOpen(item)}>
                   <NImage
@@ -245,7 +237,8 @@ export default defineComponent({
                   {data.tab === 'all' && (
                     <div
                       class={styles.favoriteBtn}
-                      onClick={() => {
+                      onClick={(e: Event) => {
+                        e.stopPropagation();
                         item.favoriteFlag = !item.favoriteFlag;
                         dubounce(() => handleFavorite(item));
                       }}>
@@ -258,7 +251,7 @@ export default defineComponent({
           </div>
         </div>
 
-        <div class={[styles.book, data.showBook && styles.show]}>
+        {/* <div class={[styles.book, data.showBook && styles.show]}>
           <div class={styles.bookWrap}>
             {data.details.map((item: any) => {
               return (
@@ -306,7 +299,16 @@ export default defineComponent({
               关闭
             </Button>
           </div>
-        </div>
+        </div> */}
+
+        <TheBook
+          show={data.showBook}
+          bookData={data.bookData}
+          rect={data.book}
+          onClose={() => {
+            data.showBook = false;
+          }}
+        />
       </div>
     );
   }

Vissa filer visades inte eftersom för många filer har ändrats