PageSourceSearch

https://www.3peaks.co.jp/catalog/2024/v2_lib/wisebook.pen.min.js

js 3peaks.co.jp collected 2026-10-08 18:49:39 UTC 20,850 bytes, 729 lines download raw bytes

1(function(){
2	wisebookpen = function(){
3		this.init();
4	}
5	
6	wisebookpen.prototype = {
7		penmode : false,
8		canvasAlphaLayer : null,
9		targetCanvas : {},
10		storageData : null,
11		
12		eraserMode : false,
13		canvasDirect : 'both',
14		isMove : false,
15		
16		penSizeMapping	: {
17			'r' : 2,
18			'm' : 6,
19			'b' : 12,
20			'selected' : 'r'
21		},
22		penColor : {
23			'yellow' : '#fffc0a',
24			'green'	: '#4eff00',
25			'blue' : '#499efd',
26			'pink' : '#ff2291',
27			'red' : '#fc1e00',
28			'selected' : 'yellow'
29		},
30		
31		line:{
32			clickSeq:0,
33			lineSeq:0,
34			page:0,
35			penSize:2,
36			penType:'pen_curve',
37			pathType:'',//opened move closed
38			oldX:0,
39			oldY:0,
40			nowX:0,
41			nowY:0,
42			oldFx:0,
43			oldFy:0,
44			penColor:'#fffc0a',
45			penAlpha:0.7
46		},
47		lineList:{},
48		
49		init : function(){
50			//usercanvas-space
51			this.canvasAlphaLayer = $('#canvasAlphaLayer');
52			this.penevent();
53			this.storageData = h5appview.wisebookStorageList.pages;
54		},
55		
56		eraserChangeElem : function(){
57			var eraserElem = $('.pen-eraser-selecter'),
58				transElem = $('.pen-trans-selecter'),
59				transVal = transElem.data('trans');
60			
61			if( !eraserElem.hasClass('selected') ) return false;	
62			
63			eraserElem.removeClass('selected');
64			if( transVal != "1" ) transElem.addClass('selected');
65			this.eraserMode = false;
66		},
67		
68		transChangeElem : function(){
69			var transElem = $('.pen-trans-selecter');
70			
71			if( this.tempPenAlpah != 1 ){
72				transElem.addClass('selected').find('i').addClass('icon-view-view_tool_check');
73			}else{
74				transElem.removeClass('selected').find('i').removeClass('icon-view-view_tool_check');
75			}
76			
77			this.line.penAlpha = this.tempPenAlpah;
78		},
79		
80		curveAndstraightChange : function(){
81			if( this.tempPenType == 'pen_curve' )	{
82				$('.pen-curve-selecter').addClass('selected');
83			}else{
84				$('.pen-straight-selecter').addClass('selected');
85			}
86			this.line.penType = this.tempPenType;
87			this.tempPenType = '';
88		},
89		
90		penevent : function(){
91		  console.log("penevent called");
92			var that = this;
93			$(document).on(viewdefind.PEN_MODE_OPEN, function(){ that.penModeOpen(); });
94			
95			$(document).on(viewdefind.VIEW_POPUP_CLOSE, function(e){ 
96			    if( PARAM.nowBusy != 'pen' ) return false;
97			    that.penModeClose();
98			    ADDONS.viewNavContainerAction('show');
99            });
100            
101			$(document).on(viewdefind.PAGE_BEFORE_EVENT, function(e, page){ that.settingTarget(); })
102			$(document).on(viewdefind.PAGE_AFTER_EVENT, function(e, page){ that.refresh(); });
103			
104			$(document).on(viewdefind.ADDONS_RESIZE, function(e){ 
105			    //phone
106			    if( viewUtils.Mobile ){
107    			     that.refresh(true); 
108			    }else{
109    			    that.targetInit();
110                    that.refresh(); 
111			    }
112				
113			});
114			$(document).on(viewdefind.VIEW_DESTROY, function(){that.destroy();});
115			
116			
117			$(document).on(viewdefind.PEN_POPOVER, function(e, elem){
118				if( $(elem).hasClass('pen-thick-popover') ){
119					$(elem).find('.pen-block .thick-line-'+that.penSizeMapping.selected).addClass('selected');
120				}else if( $(elem).hasClass('pen-color-popover') ){
121					$(elem).find('.pen-block .pen-color-'+that.penColor.selected).addClass('selected');
122				}
123			});
124			
125			PARAM.wisebook.on('tap', '.pen-curve-selecter, .pen-straight-selecter, .pen-trans-selecter, .pen-eraser-selecter', function(){
126				var clicked = $(this);
127				
128				if( clicked.hasClass('pen-curve-selecter') || clicked.hasClass('pen-straight-selecter')  ){
129					if( that.eraserMode ){
130						that.eraserChangeElem();
131						that.transChangeElem();
132						that.curveAndstraightChange();
133					}else{
134						$('.pen-curve-selecter, .pen-straight-selecter').removeClass('selected');
135						if( clicked.hasClass('pen-curve-selecter') )
136							that.line.penType = 'pen_curve';
137						else
138							that.line.penType = 'pen_straight';
139						
140						clicked.addClass('selected');
141					}
142				}else if( clicked.hasClass('pen-trans-selecter') ){
143					if( that.eraserMode ){
144						that.eraserChangeElem();
145						that.curveAndstraightChange();
146						that.transChangeElem();
147					}else{
148						clicked.toggleClass('selected');
149						
150						
151						if( clicked.hasClass('selected') ){
152							clicked.find('i').addClass('icon-view-view_tool_check');
153							that.line.penAlpha = 0.7;
154							clicked.attr('data-trans', that.line.penAlpha);
155						}else{
156							clicked.find('i').removeClass('icon-view-view_tool_check');
157							that.line.penAlpha = 1;
158							clicked.attr('data-trans', that.line.penAlpha);
159						}
160					}
161					
162				}else  if( clicked.hasClass('pen-eraser-selecter') ){
163					if( clicked.hasClass('selected') ) return false;
164					$(this).addClass('selected');
165					$('.pen-curve-selecter, .pen-straight-selecter').removeClass('selected');
166					$('.pen-trans-selecter').removeClass('selected').find('i').removeClass('icon-view-view_tool_check');
167					
168					that.eraserMode = true;
169					that.tempPenType = that.line.penType;
170					that.tempPenAlpah = that.line.penAlpha;
171					that.line.penAlpha=1;
172					that.line.penType = 'pentool_eraser';
173				}
174				
175			});
176			
177			PARAM.wisebook.on('tap', '.penl-linelist-selecter, .pen-color-selecter', function(){
178				if( $(this).hasClass('penl-linelist-selecter') ){
179					$('.penl-linelist-selecter').removeClass('selected');
180					that.line.penSize = that.penSizeMapping[$(this).data('thick')];
181					$(this).addClass('selected');
182					that.penSizeMapping['selected'] = $(this).data('thick');
183					
184				}else if( $(this).hasClass('pen-color-selecter') ){
185					$('.pen-color-selecter').removeClass('selected');
186					var selected = that.penColor['selected'];
187					var newSelected = $(this).data('color');
188					that.line.penColor = that.penColor[$(this).data('color')];
189					
190					$(this).addClass('selected');
191					that.penColor['selected'] = $(this).data('color');
192					$('.pen-color-box').removeClass('color-'+selected).addClass('color-'+newSelected);
193				}
194				
195				$('.view-modal-overlay').trigger('tap');
196			});
197			
198			PARAM.wisebook.on('tap', '.pen-eraserall-selecter', function(){
199			    viewMessageProc.confirm( PARAM.viewLang.penAllPageCanvasDelete, PARAM.viewLang.confirm_title,
200			        function(){
201    			        that.removeCanvasStorageData();
202			        }
203			     );
204			});
205			
206			console.log("regist event ",viewUtils.START_EV);//2020-12-24 ここでタッチパネルなのにmousedownが来る
207			this.canvasAlphaLayer.on(viewUtils.START_EV, that.penDragStartHandler);
208			
209			let has_touch= false;
210			if("ontouch" in window){
211			  console.log("has_touch");
212			  has_touch = true;
213			}
214			
215			if( viewUtils.device == 'pc' &&  has_touch == false ){
216				this.canvasAlphaLayer.on('mouseleave.pen2', function(){
217					if( !that.isMove ) return false;
218					
219					that.lineDataToBook();
220					that.line.oldFy=0;
221					that.line.oldFx=0;
222					that.lineList={};
223					that.isMove  = false;
224					
225					$(this).unbind(viewUtils.MOVE_EV);
226					$(this).unbind(viewUtils.END_EV); 
227				});
228			}
229			
230		},
231		
232		/*=== pen start event ===*/
233		penDragStartHandler : function(e){
234			if( e.originalEvent.changedTouches && e.originalEvent.touches.length > 1) return false;
235			
236			var that = wisebookpen,
237				line = that.line,
238				x, y, page,
239				point = e.originalEvent.changedTouches ? e.originalEvent.changedTouches[0] : e,
240				target = $(e.target),
241				onepage = parseInt( $(e.target).attr('onepage') );
242			
243			x = point.pageX - target.offset().left;
244			y = point.pageY - target.offset().top;
245						
246			if( onepage == 0 ) page = PARAM.getUserFullPositionPage(x / PARAM.transformInfo.scale );
247			else page = onepage;
248			
249			line.clickSeq = PARAM.uniqID();
250			line.lineSeq++;
251			line.oldX = x;
252			line.oldY = y;
253			
254			line.page = page;			
255			that.lineList = {};
256			that.isMove = true;
257			
258			that.canvasAlphaLayer.bind(viewUtils.MOVE_EV, that.penDragMoveHandler);
259			that.canvasAlphaLayer.bind(viewUtils.END_EV, that.penDragEndtHandler);
260		},
261		
262		/*=== pen move event ===*/
263		penDragMoveHandler : function(e){
264			var that = wisebookpen, 
265				line = that.line,
266				x, y,
267				point = e.originalEvent.changedTouches ? e.originalEvent.changedTouches[0] : e,
268				target = $(e.target),
269				onepage = parseInt( $(e.target).attr('onepage') );
270			
271			if( !that.isMove ) return false;
272			
273			x = point.pageX - target.offset().left;
274			y = point.pageY - target.offset().top;
275			
276			if( onepage == 0 ) page = PARAM.getUserFullPositionPage(x / PARAM.transformInfo.scale);
277			else page = onepage;
278			
279			if (line.penType=='pen_straight'){
280				if (line.oldFy==0 && line.oldFx==0){
281					if (Math.abs(line.oldX-x) ==0 && Math.abs(line.oldY-y)==0) {
282						return;
283					} else if (Math.abs(line.oldX-x) > Math.abs(line.oldY-y)){
284						y = line.oldFy = line.oldY;
285					} else {
286						x = line.oldFx = line.oldX;
287						line.page = (that.lineList.length>0) ? that.lineList[0].page:line.page;
288						page=line.page;
289					}
290				} else if (line.oldFy>0){
291					y = line.oldY = line.oldFy;
292				} else if (line.oldFx>0){
293					x = line.oldX = line.oldFx;
294					line.page = (that.lineList.length>0) ? that.lineList[0].page:line.page;
295					page=line.page;
296				}
297			}
298			
299			if ( (PARAM.direct == 'ltr' && line.page < page) || (PARAM.direct == 'rtl' && line.page > page)  ) {
300				line.lineSeq++;
301				line.oldX = x;
302				line.oldY = y;
303				line.pathType = 'move';
304				that.drawLine(line);
305				
306				line.lineSeq++;
307				line.page = page;
308				line.pathType = 'move';
309				that.drawLine(line);
310				
311				line.clickSeq = PARAM.uniqID();
312				line.lineSeq++;
313				line.page = page;
314				line.nowX = x;
315				line.nowY = y;
316
317				return false;
318			}else if( (PARAM.direct == 'ltr' && line.page > page) || (PARAM.direct == 'rtl' && line.page < page) ){
319				line.lineSeq++;
320				line.oldX = x;
321				line.oldY = y;
322				line.pathType = 'move';
323				that.drawLine(line);
324				
325				line.lineSeq++;
326				line.page = page;
327				line.pathType = 'move';
328				that.drawLine(line);
329				
330				line.clickSeq = PARAM.uniqID();
331				line.lineSeq++;
332				line.page = page;
333				line.nowX = x;
334				line.nowY = y;
335				
336				return false;
337			}
338			
339			line.lineSeq++;
340			line.page=page;
341			line.nowX = x;
342			line.nowY = y;
343			that.drawLine(line);
344			line.oldX = x;
345			line.oldY = y;
346			line.pathType = 'move';
347		},
348		
349		/*=== pen end event ===*/
350		penDragEndtHandler : function(e){
351			var that = wisebookpen,
352				line = that.line,
353				point = e.originalEvent.changedTouches ? e.originalEvent.changedTouches[0] : e;
354
355			that.lineDataToBook();
356
357			line.oldFy=0;
358			line.oldFx=0;
359			line.oldX=0;
360			line.oldX=0;
361			
362			that.isMove  = false;
363			
364			that.canvasAlphaLayer.unbind(viewUtils.MOVE_EV);
365			that.canvasAlphaLayer.unbind(viewUtils.END_EV); 
366		},
367		
368		drawLine : function(line){
369			var ccanvas, context;
370			//save line extend
371			var saveLine = {
372				clickSeq:0,
373				lineSeq:0,
374				page:0,
375				penSize:0,
376				penType:'',
377				pathType:'',
378				oldX:0,
379				oldY:0,
380				nowX:0,
381				nowY:0,
382				oldFx:0,
383				oldFy:0,
384				penColor:'',
385				penAlpha:0
386			};
387			
388			$.extend(saveLine, line);
389			
390			if (line.penType=='pentool_eraser'){
391				ccanvas = this.targetCanvas[saveLine.page];
392				context = ccanvas.getContext("2d");
393				/*
394if( PARAM.viewMode == "twopage" ){
395				    var nowX = saveLine.nowX/PARAM.transformInfo.scale;
396                    var nowY = saveLine.nowY/PARAM.transformInfo.scale;
397                    var oldX = saveLine.oldX/PARAM.transformInfo.scale;
398                    var oldY = saveLine.oldY/PARAM.transformInfo.scale;
399				
400					nowX -= this.getPageCanvasLeftMargin(saveLine.page);
401					oldX -= this.getPageCanvasLeftMargin(saveLine.page);
402				}
403*/
404				var nowX = saveLine.nowX/PARAM.transformInfo.scale;
405                var nowY = saveLine.nowY/PARAM.transformInfo.scale;
406                var oldX = saveLine.oldX/PARAM.transformInfo.scale;
407                var oldY = saveLine.oldY/PARAM.transformInfo.scale;
408			
409				nowX -= this.getPageCanvasLeftMargin(saveLine.page);
410				oldX -= this.getPageCanvasLeftMargin(saveLine.page);
411				
412				context.strokeStyle = saveLine.penColor;
413    			context.lineWidth = saveLine.penSize;
414    			context.globalCompositeOperation = "destination-out";
415				context.strokeStyle = "rgba(255,255,255,1)";
416				context.lineWidth = 10;
417    			context.lineJoin= "round";
418    			context.lineCap = "round";
419    			
420				context.beginPath();
421				context.moveTo(oldX, oldY);
422    			context.lineTo(nowX, nowY);
423    			context.stroke();
424                context.closePath();
425                
426                saveLine.nowX = nowX;
427    			saveLine.nowY = nowY;
428    			saveLine.oldX = oldX;
429    			saveLine.oldY = oldY;
430                
431                if( !this.lineList[saveLine.page] ) 
432    				this.lineList[saveLine.page] = [];
433    			
434    			this.lineList[saveLine.page].push(saveLine);
435    			
436			}else{
437				ccanvas = this.canvasAlphaLayer[0];
438				context = ccanvas.getContext("2d");
439				var nowX = saveLine.nowX/PARAM.transformInfo.scale;
440                var nowY = saveLine.nowY/PARAM.transformInfo.scale;
441                var oldX = saveLine.oldX/PARAM.transformInfo.scale;
442                var oldY = saveLine.oldY/PARAM.transformInfo.scale;
443                
444                context.strokeStyle = saveLine.penColor;
445    			context.lineWidth = saveLine.penSize;
446    			context.lineJoin= "round";
447    			context.lineCap = "round";
448    			context.globalAlpha = 1;
449    			context.globalCompositeOperation='source-over';
450    			
451    			context.beginPath();
452    			context.moveTo(oldX, oldY);
453    			context.lineTo(nowX, nowY);
454                context.stroke();
455                context.closePath();
456                
457                saveLine.nowX = nowX;
458    			saveLine.nowY = nowY;
459    			saveLine.oldX = oldX;
460    			saveLine.oldY = oldY;
461    			
462    			if( PARAM.viewMode == "twopage" ){
463    				saveLine.nowX -= this.getPageCanvasLeftMargin(saveLine.page);
464    				saveLine.oldX -= this.getPageCanvasLeftMargin(saveLine.page);
465    			}
466    			
467    			if( !this.lineList[saveLine.page] ) 
468    				this.lineList[saveLine.page] = [];
469    			
470    			this.lineList[saveLine.page].push(saveLine);
471			}
472		},
473		
474		//linedata -> drwing and storage save
475		lineDataToBook : function(){
476			var that = this;
477			
478			for( var p in this.lineList ){
479				var data = this.lineList[p];
480				
481				data[0].pathType = 'opened';
482				data[ data.length -1 ].pathType = 'closed';
483				
484				var canvas = this.targetCanvas[p],
485					context = canvas.getContext("2d");
486				
487				for( var l in data ){
488					var line = data[l];
489					
490					//eraser typeはしなくても前に描く
491					if( line.penType =='pentool_eraser' ) {
492						line.nowX /= PARAM.spaceScale;
493						line.nowY /= PARAM.spaceScale;
494						line.oldX /= PARAM.spaceScale;
495						line.oldY /= PARAM.spaceScale;
496						this.storageData[p].canvasList.push(line);
497						
498						continue;
499					}
500					
501					if (line.pathType=='opened'){
502						context.beginPath();
503					}
504					
505					context.globalCompositeOperation = 'source-over';
506					context.globalAlpha = line.penAlpha;
507					context.strokeStyle = line.penColor;
508					context.lineWidth = line.penSize;
509					context.lineJoin= "round";
510					context.lineCap = "round";
511					
512					context.moveTo(line.oldX, line.oldY);
513					context.lineTo(line.nowX, line.nowY);
514					if (line.pathType=='closed'){
515						context.stroke();
516						context.closePath();
517						context.beginPath();
518					}
519					
520					line.nowX /= PARAM.spaceScale;
521					line.nowY /= PARAM.spaceScale;
522					line.oldX /= PARAM.spaceScale;
523					line.oldY /= PARAM.spaceScale;
524					this.storageData[p].canvasList.push(line);
525					
526				}
527				
528				h5appview.setStorageData(p);
529			}
530			
531			var layerCanvas = this.canvasAlphaLayer[0];
532			layerCanvas.getContext("2d").clearRect(0, 0, layerCanvas.width, layerCanvas.height);
533		},
534		
535		
536		//storage -> 紙面
537		storageDataToBook : function(){
538			for( var p in PARAM.side.view ){
539				var page = PARAM.side.view[p];
540				if( page == 0 ) continue;
541				
542				var data = this.storageData[page].canvasList,
543					canvas = this.targetCanvas[page],
544					context = canvas.getContext("2d");
545				
546				if(data.length <= 0) continue;
547				context.clearRect(0, 0, canvas.width, canvas.height);
548				
549				for( var l in data ){
550					var lineobj = data[l];
551					if( lineobj.pathType=='opened' ){
552						context.beginPath();
553					}
554					
555					var nowX=lineobj.nowX * PARAM.spaceScale;
556					var nowY=lineobj.nowY * PARAM.spaceScale;
557					var oldX=lineobj.oldX * PARAM.spaceScale;
558					var oldY=lineobj.oldY * PARAM.spaceScale;
559					
560					context.lineJoin= "round";
561					context.lineCap = "round";
562					
563					if (lineobj.penType=='pentool_eraser'){
564						context.globalCompositeOperation = "destination-out";
565						context.strokeStyle = "rgba(255,255,255,1)";
566						context.globalAlpha = 1;
567						context.lineWidth = 10;
568					}else{
569						context.globalCompositeOperation = 'source-over';
570						context.globalAlpha = lineobj.penAlpha;
571						context.strokeStyle = lineobj.penColor;
572						context.lineWidth = lineobj.penSize;
573					}
574					
575					context.moveTo(oldX, oldY);
576					context.lineTo(nowX, nowY);
577					if (lineobj.pathType=='closed'){
578						context.stroke();
579						context.closePath();
580					}
581				}
582			}
583		},
584			
585		setPageCanvasSize : function(){
586			var widthsize = PARAM.imageWidth,
587				left = 0, onepage = 0;
588			
589			if( PARAM.viewMode == 'twopage' ) {
590				this.canvasDirect = 'both'
591				if( PARAM.side.left == 0 ){
592					this.canvasDirect = 'right';
593					widthsize /= 2;
594					left = PARAM.side.rightstartx;
595					onepage = PARAM.currentpage
596					
597				}else if( PARAM.side.right == 0 ){
598					this.canvasDirect = 'left';
599					left = 0;
600					widthsize /= 2;
601					onepage = PARAM.currentpage;
602				}
603			}else{
604				this.canvasDirect = 'left';
605				onepage = PARAM.currentpage;
606			}
607			
608			//onepage setting
609			this.canvasAlphaLayer.css({width : widthsize, height : PARAM.imageHeight, left : left}).attr({width : widthsize, height : PARAM.imageHeight, 'onepage': onepage});
610		},
611		
612		getPageCanvasLeftMargin : function(page){
613			if( this.canvasDirect == 'both' ){
614				if( PARAM.side.right == page ) return PARAM.side.rightstartx;
615			}
616			
617			return 0;
618		},
619		
620		penModeOpen : function(){
621			this.penmode = true;
622			
623			PARAM.isNaviMove = false;
624			if( viewUtils.device == 'pc'){
625				$(document).trigger(viewdefind.NAV_MOVE_DISABLE, true);
626			}
627			
628			htmlview.viewActionDisable();
629			if( viewUtils.device == 'pc' && PARAM.isZoom )
630				htmlview.viewContain.css({"cursor":"default"});
631			
632			this.refresh();
633		},
634		
635		penModeClose : function(){
636			this.penmode = false;
637			//this.storageDataToBook();
638			
639			PARAM.isNaviMove = true;
640			$(document).trigger(viewdefind.NAV_MOVE_DISABLE, false);
641			htmlview.viewActionEnable();
642			
643			this.canvasAlphaLayer.css({ width : '', height : '' }).attr({width : '', height : ''});
644			this.canvasDirect = 'both';
645			
646			if( viewUtils.device == 'pc' && PARAM.isZoom )
647				htmlview.viewContain.css({"cursor":"move"});
648		},
649		
650		settingTarget : function(){
651			if( Object.keys( this.targetCanvas ).length > PARAM.domStorageLimit ){
652    			this.targetCanvas = {};
653			}
654            
655			for( var v in  PARAM.side.view){
656				var page = PARAM.side.view[v];
657				if(page == 0) continue;	
658				
659				var DOMpage = page + PARAM.cover;				
660				if( !this.targetCanvas[page] )
661					this.targetCanvas[page] = $('.p'+DOMpage).find('.collections-space .usercanvas-space')[0];
662			}			
663		},
664		
665		removeCanvasStorageData : function(){
666		
667			for( var p in PARAM.side.view ){
668				var page = PARAM.side.view[p];
669				if( page == 0 ) continue;
670				var canvas = this.targetCanvas[page];
671				canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
672				
673				this.storageData[page].canvasList = [];
674				h5appview.setStorageData(page);
675			}
676			
677			canvas = this.canvasAlphaLayer[0],
678			canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
679		},
680		
681		targetInit : function(){
682			for( var t in this.targetCanvas ){
683				var canvas = this.targetCanvas[t];
684				if( canvas ) continue;
685				canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
686			}
687		},
688		
689		refresh : function( resize ){
690			var that = this;
691			//resizeが発生した場合initしてからもう一度描く
692			this.settingTarget();
693			
694			//phone only
695			if( resize && this.penmode ){
696			    this.penModeClose();
697			    ADDONS.closeModal();
698			    setTimeout(function(){
699					that.storageDataToBook();
700				}, 0);
701    			return false;
702			}
703			
704			if( this.penmode ) {
705				this.setPageCanvasSize();
706			}else{
707				for( var v in PARAM.side.view ){
708					var page = PARAM.side.view[v];
709					if(page == 0) continue;
710					
711					var DOMpage = page;
712                    DOMpage += PARAM.cover;
713					
714					if( !this.targetCanvas[page] )
715						this.targetCanvas[page] = $('.p'+DOMpage).find('.collections-space .usercanvas-space')[0];			
716				}
717				
718				setTimeout(function(){
719					that.storageDataToBook();
720				}, 0);
721			}
722		},
723		
724		destroy : function(){			
725			this.canvasAlphaLayer.unbind(viewUtils.START_EV);
726			this.canvasAlphaLayer.unbind('mouseleave.pen');
727		}
728	};
729})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.