<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>escapegame-2022/tsubasa/blender_three.js/OrbitControls.js at master - SKIP/escapegame-2022</title>
<meta property="og:title" content="escapegame-2022/tsubasa/blender_three.js/OrbitControls.js at master - SKIP/escapegame-2022" />
<meta property="og:type" content="object" />
<meta property="og:url" content="http://localhost:8880/SKIP/escapegame-2022/blob/master/tsubasa/blender_three.js/OrbitControls.js" />
<meta property="og:image" content="https://www.yatex.org/gitbucket/SKIP/_avatar" />
<link rel="icon" href="https://www.yatex.org/gitbucket/assets/common/images/gitbucket.png?20240601154850" type="image/vnd.microsoft.icon" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://www.yatex.org/gitbucket/assets/vendors/google-fonts/css/source-sans-pro.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/bootstrap-3.4.1/css/bootstrap.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/octicons-4.4.0/octicons.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/bootstrap-datetimepicker-4.17.44/css/bootstrap-datetimepicker.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/colorpicker/css/bootstrap-colorpicker.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/color-themes-for-google-code-prettify/github-v2.min.css?20240601154850" type="text/css" rel="stylesheet"/>
<link href="https://www.yatex.org/gitbucket/assets/vendors/facebox/facebox.css?20240601154850" rel="stylesheet"/>
<link href="https://www.yatex.org/gitbucket/assets/vendors/AdminLTE-2.4.2/css/AdminLTE.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/AdminLTE-2.4.2/css/skins/skin-green-light.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/font-awesome-4.7.0/css/font-awesome.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/jquery-ui/jquery-ui.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/jquery-ui/jquery-ui.structure.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/jquery-ui/jquery-ui.theme.min.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/common/css/gitbucket.css?20240601154850" rel="stylesheet">
<link href="https://www.yatex.org/gitbucket/assets/vendors/tipped/tipped.css?20240601154850" rel="stylesheet">
<script src="https://www.yatex.org/gitbucket/assets/vendors/jquery/jquery-3.5.1.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/jquery-ui/jquery-ui.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/dropzone/dropzone.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/common/js/validation.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/common/js/gitbucket.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/bootstrap-3.4.1/js/bootstrap.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/bootstrap3-typeahead/bootstrap3-typeahead.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/bootstrap-datetimepicker-4.17.44/js/moment.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/bootstrap-datetimepicker-4.17.44/js/bootstrap-datetimepicker.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/colorpicker/js/bootstrap-colorpicker.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/google-code-prettify/prettify.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/elastic/jquery.elastic.source.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/facebox/facebox.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/jquery-hotkeys/jquery.hotkeys.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/jquery-textcomplete-1.8.4/jquery.textcomplete.min.js?20240601154850"></script>
<script src="https://www.yatex.org/gitbucket/assets/vendors/tipped/tipped.min.js?20240601154850"></script>
<meta name="go-import" content="www.yatex.org/gitbucket/SKIP/escapegame-2022 git https://www.yatex.org/gitbucket/git/SKIP/escapegame-2022.git" />
<script src="https://www.yatex.org/gitbucket/assets/vendors/AdminLTE-2.4.2/js/adminlte.min.js?20240601154850" type="text/javascript"></script>
<style type="text/css">.content, .sidebar, .skin-green-light div.main-sidebar {
background: #efe;
}</style>
</head>
<body class="skin-green-light page-load sidebar-mini ">
<div class="wrapper">
<header class="main-header">
<a href="https://www.yatex.org/gitbucket/" class="logo">
<span class="logo-mini"><img src="https://www.yatex.org/gitbucket/assets/common/images/gitbucket.svg?20240601154850" alt="GitBucket" /></span>
<span class="logo-lg">
<img src="https://www.yatex.org/gitbucket/assets/common/images/gitbucket.svg?20240601154850" alt="GitBucket" />
<span class="header-title strong">GitBucket</span>
</span>
</a>
<nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button-->
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button" title="Toggle navigation">
<span class="sr-only">Toggle navigation</span>
</a>
<form id="search" action="https://www.yatex.org/gitbucket/search" method="GET" class="pc navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" name="query" id="navbar-search-input" class="form-control" placeholder="Find a repository" aria-label="Search"/>
</div>
</form>
<ul class="pc nav navbar-nav">
<li><a href="https://www.yatex.org/gitbucket/dashboard/pulls">Pull requests</a></li>
<li><a href="https://www.yatex.org/gitbucket/dashboard/issues">Issues</a></li>
<li><a href="https://www.yatex.org/gitbucket/gist">Snippets</a></li>
</ul>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li class="dropdown notifications-menu">
<a class="dropdown-toggle menu" data-toggle="dropdown" href="#" aria-label="Create new…">
<i class="octicon octicon-plus" style="color: black;"></i><span class="caret" style="color: black; vertical-align: middle;"></span>
</a>
<ul class="dropdown-menu pull-right" style="width: auto;">
<li>
<ul class="menu">
<li><a href="https://www.yatex.org/gitbucket/new">New repository</a></li>
<li><a href="https://www.yatex.org/gitbucket/groups/new">New group</a></li>
</ul>
</li>
</ul>
</li>
<li class="dropdown notifications-menu">
<a class="dropdown-toggle menu" data-toggle="dropdown" href="#" data-toggle="tooltip" data-placement="bottom" title="Signed is as j2311">
<img src="https://www.gravatar.com/avatar/6887b4acd79bba29f3b92ca6ba6a6d17?s=16&d=retro&r=g" class="avatar-mini" style="width: 16px; height: 16px;"
alt="@j2311" /><span class="caret" style="color: black; vertical-align: middle;"></span>
</a>
<ul class="dropdown-menu pull-right" style="width: auto;">
<li>
<ul class="menu">
<li><a href="https://www.yatex.org/gitbucket/j2311">Your profile</a></li>
<li><a href="https://www.yatex.org/gitbucket/j2311/_edit">Account settings</a></li>
<li><a href="https://www.yatex.org/gitbucket/signout">Sign out</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</header>
<div class="main-sidebar">
<div class="sidebar">
<ul class="sidebar-menu">
<li class = "menu-item-hover active">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022">
<i class="menu-icon octicon octicon-code"></i>
<span>Files</span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/branches">
<i class="menu-icon octicon octicon-git-branch"></i>
<span>Branches</span>
<span class="pull-right-container"><span class="label label-primary pull-right">1</span></span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/releases">
<i class="menu-icon octicon octicon-tag"></i>
<span>Releases</span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/issues">
<i class="menu-icon octicon octicon-issue-opened"></i>
<span>Issues</span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/pulls">
<i class="menu-icon octicon octicon-git-pull-request"></i>
<span>Pull requests</span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/issues/labels">
<i class="menu-icon octicon octicon-tag"></i>
<span>Labels</span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/issues/priorities">
<i class="menu-icon octicon octicon-flame"></i>
<span>Priorities</span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/issues/milestones">
<i class="menu-icon octicon octicon-milestone"></i>
<span>Milestones</span>
</a>
</li>
<li class = "menu-item-hover ">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/wiki">
<i class="menu-icon octicon octicon-book"></i>
<span>Wiki</span>
</a>
</li>
</ul>
</div>
</div>
<div class="content-wrapper">
<div class="content body clearfix">
<div class="headbar">
<div class="container">
<div class="head">
<div class="pull-right">
<div class="btn-group" >
<button class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown">
<span class="strong"
>
Not watching
</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right">
<li>
<a href="#" class="watch" data-id="watching">
<i class="octicon"></i>
<span class="notification-label strong">Watching</span>
<div class="muted small">Notify all conversations.</div>
</a>
</li>
<li>
<a href="#" class="watch" data-id="not_watching">
<i class="octicon octicon-check"></i>
<span class="notification-label strong">Not watching</span>
<div class="muted small">Notify when participating.</div>
</a>
</li>
<li>
<a href="#" class="watch" data-id="ignoring">
<i class="octicon"></i>
<span class="notification-label strong">Ignoring</span>
<div class="muted small">Never notify.</div>
</a>
</li>
</ul>
</div>
<script>
$(function(){
$('a.watch').click(function(){
var selected = $(this);
var notification = selected.data('id');
$.post('https://www.yatex.org/gitbucket/SKIP/escapegame-2022/watch',
{ notification : notification },
function(){
$('a.watch i.octicon-check').removeClass('octicon-check');
$('a.watch[data-id=' + notification + '] i').addClass('octicon-check');
// Update button label
var label = selected.find('span.notification-label').text().trim();
selected.parents('div.btn-group').find('button>span.strong').text(label);
}
);
return false;
});
});
</script>
<a class="btn btn-default btn-sm" href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/fork" rel="facebox">
<span class="strong"><i class="octicon octicon-repo-forked"></i>Fork</span><span class="muted">: 7</span>
</a>
<form id="fork-form" method="post" action="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/fork" style="display: none;">
<input type="hidden" name="account" value="j2311"/>
</form>
</div>
<i class="mega-octicon octicon-repo"></i>
<a href="https://www.yatex.org/gitbucket/SKIP">SKIP</a> / <a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022" class="strong">escapegame-2022</a>
</div>
</div>
</div>
<style>
.prettyprint {
tab-size: 8
}
</style>
<div class="head">
<div class="pull-right hide-if-blame"><div class="btn-group">
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/blob/7a630f0bef6ef4e4fa22f5c34a655f7c38f16adc/tsubasa/blender_three.js/OrbitControls.js" data-hotkey="y" style="display: none;">Transfer to URL with SHA</a>
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/find/master" class="btn btn-sm btn-default" data-hotkey="t">Find file</a>
</div></div>
<div class="line-age-legend">
<span>Newer</span>
<ol>
<li class="heat1"></li>
<li class="heat2"></li>
<li class="heat3"></li>
<li class="heat4"></li>
<li class="heat5"></li>
<li class="heat6"></li>
<li class="heat7"></li>
<li class="heat8"></li>
<li class="heat9"></li>
<li class="heat10"></li>
</ol>
<span>Older</span>
</div>
<div id="branchCtrlWrapper" style="display:inline;">
<div class="btn-group" style="min-width: 200px;">
<button class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown">
<span class="muted">branch:</span>
<span class="strong"
style="display:inline-block; vertical-align:bottom; overflow-x:hidden; max-width:200px; text-overflow:ellipsis">
master
</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<ul class="nav nav-tabs">
<li class="active" id="branch-control-tab-branches"><a href="javascript:void(0);" class="nav-item" id="nav-item-branches">Branches</a></li>
<li id="branch-control-tab-tags"><a href="javascript:void(0);" class="nav-item" id="nav-item-tags">Tags</a></li>
<li><button id="branch-control-close" class="pull-right">×</button></li>
</ul>
<li>
<input id="branch-control-input" type="text" class="form-control input-sm dropdown-filter-input"/>
</li>
<li><a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/blob/master/tsubasa/blender_three.js/OrbitControls.js">
<i class="octicon octicon-check"></i>
master</a></li>
</li>
</ul>
</div>
<script>
$(function(){
$('#branch-control-input').parent().click(function(e) {
e.stopPropagation();
});
$('#branch-control-close').click(function() {
$('[data-toggle="dropdown"]').parent().removeClass('open');
});
$('#branch-control-input').keyup(function() {
updateBranchControlListFilter();
});
$('.btn-group').click(function() {
$('#branch-control-input').val('');
//$('.dropdown-menu li').show();
$('#create-branch').hide();
});
$('#nav-item-branches').click(function(e) {
e.stopPropagation();
updateBranchControlList('branches');
});
$('#nav-item-tags').click(function(e) {
e.stopPropagation();
updateBranchControlList('tags');
});
function updateBranchControlList(active) {
if (active == 'branches') {
$('li#branch-control-tab-branches').addClass('active');
$('li#branch-control-tab-tags').removeClass('active');
$('li.branch-control-item-branch').show();
$('li.branch-control-item-branch > a').addClass('active');
$('li.branch-control-item-tag').hide();
$('li.branch-control-item-tag > a').removeClass('active');
$('#branch-control-input').attr('placeholder', 'Find branch ...');
} else if (active == 'tags') {
$('li#branch-control-tab-branches').removeClass('active');
$('li#branch-control-tab-tags').addClass('active');
$('li.branch-control-item-branch').hide();
$('li.branch-control-item-branch > a').removeClass('active');
$('li.branch-control-item-tag').show();
$('li.branch-control-item-tag > a').addClass('active');
$('#branch-control-input').attr('placeholder', 'Find tag ...');
}
updateBranchControlListFilter();
}
function updateBranchControlListFilter() {
const inputVal = $('#branch-control-input').val();
$.each($('#branch-control-input').parent().parent().find('a.active').not('.nav-item'), function(index, elem) {
if (!inputVal || !elem.text.trim() || elem.text.trim().toLowerCase().indexOf(inputVal.toLowerCase()) >= 0) {
$(elem).parent().show();
} else {
$(elem).parent().hide();
}
});
if ($('li#branch-control-tab-branches.active').length > 0) {
}
}
// Initialize the branch control list
updateBranchControlList('branches');
});
</script>
</div>
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/tree/master">escapegame-2022</a> /
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/tree/master/tsubasa">tsubasa</a> /
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/tree/master/tsubasa/blender_three.js">blender_three.js</a> /
OrbitControls.js
</div>
<div class="box-header" style="line-height: 28px;">
<img src="https://www.gravatar.com/avatar/96a94f732f7c0250e2958855bb031406?s=20&d=retro&r=g" class="avatar-mini" style="width: 20px; height: 20px;"
alt="@tsubasa" />
tsubasa
<span class="muted">
<span data-toggle="tooltip" title="2022-12-06 14:38:48">
on 6 Dec 2022
</span>
</span>
<span class="label label-default">26 KB</span>
<a href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/commit/7a630f0bef6ef4e4fa22f5c34a655f7c38f16adc" class="commit-message">add</a>
<div class="btn-group pull-right">
<a class="btn btn-sm btn-default" href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/raw/7a630f0bef6ef4e4fa22f5c34a655f7c38f16adc/tsubasa/blender_three.js/OrbitControls.js">Raw</a>
<a class="btn btn-sm btn-default blame-action" href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/blame/7a630f0bef6ef4e4fa22f5c34a655f7c38f16adc/tsubasa/blender_three.js/OrbitControls.js"
data-url="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/get-blame/7a630f0bef6ef4e4fa22f5c34a655f7c38f16adc/tsubasa/blender_three.js/OrbitControls.js" data-repository="https://www.yatex.org/gitbucket/SKIP/escapegame-2022">Blame</a>
<a class="btn btn-sm btn-default" href="https://www.yatex.org/gitbucket/SKIP/escapegame-2022/commits/master/tsubasa/blender_three.js/OrbitControls.js">History</a>
</div>
</div>
<div class="box-content-bottom">
<pre class="prettyprint linenums blob no-renderable ">( function () {
// This set of controls performs orbiting, dollying (zooming), and panning.
// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
//
// Orbit - left mouse / touch: one-finger move
// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
// Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move
const _changeEvent = {
type: 'change'
};
const _startEvent = {
type: 'start'
};
const _endEvent = {
type: 'end'
};
class OrbitControls extends THREE.EventDispatcher {
constructor( object, domElement ) {
super();
this.object = object;
this.domElement = domElement;
this.domElement.style.touchAction = 'none'; // disable touch scroll
// Set to false to disable this control
this.enabled = true;
// "target" sets the location of focus, where the object orbits around
this.target = new THREE.Vector3();
// How far you can dolly in and out ( PerspectiveCamera only )
this.minDistance = 0;
this.maxDistance = Infinity;
// How far you can zoom in and out ( OrthographicCamera only )
this.minZoom = 0;
this.maxZoom = Infinity;
// How far you can orbit vertically, upper and lower limits.
// Range is 0 to Math.PI radians.
this.minPolarAngle = 0; // radians
this.maxPolarAngle = Math.PI; // radians
// How far you can orbit horizontally, upper and lower limits.
// If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI )
this.minAzimuthAngle = - Infinity; // radians
this.maxAzimuthAngle = Infinity; // radians
// Set to true to enable damping (inertia)
// If damping is enabled, you must call controls.update() in your animation loop
this.enableDamping = false;
this.dampingFactor = 0.05;
// This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
// Set to false to disable zooming
this.enableZoom = true;
this.zoomSpeed = 1.0;
// Set to false to disable rotating
this.enableRotate = true;
this.rotateSpeed = 1.0;
// Set to false to disable panning
this.enablePan = true;
this.panSpeed = 1.0;
this.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
// Set to true to automatically rotate around the target
// If auto-rotate is enabled, you must call controls.update() in your animation loop
this.autoRotate = false;
this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60
// The four arrow keys
this.keys = {
LEFT: 'ArrowLeft',
UP: 'ArrowUp',
RIGHT: 'ArrowRight',
BOTTOM: 'ArrowDown'
};
// Mouse buttons
this.mouseButtons = {
LEFT: THREE.MOUSE.ROTATE,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.PAN
};
// Touch fingers
this.touches = {
ONE: THREE.TOUCH.ROTATE,
TWO: THREE.TOUCH.DOLLY_PAN
};
// for reset
this.target0 = this.target.clone();
this.position0 = this.object.position.clone();
this.zoom0 = this.object.zoom;
// the target DOM element for key events
this._domElementKeyEvents = null;
//
// public methods
//
this.getPolarAngle = function () {
return spherical.phi;
};
this.getAzimuthalAngle = function () {
return spherical.theta;
};
this.getDistance = function () {
return this.object.position.distanceTo( this.target );
};
this.listenToKeyEvents = function ( domElement ) {
domElement.addEventListener( 'keydown', onKeyDown );
this._domElementKeyEvents = domElement;
};
this.saveState = function () {
scope.target0.copy( scope.target );
scope.position0.copy( scope.object.position );
scope.zoom0 = scope.object.zoom;
};
this.reset = function () {
scope.target.copy( scope.target0 );
scope.object.position.copy( scope.position0 );
scope.object.zoom = scope.zoom0;
scope.object.updateProjectionMatrix();
scope.dispatchEvent( _changeEvent );
scope.update();
state = STATE.NONE;
};
// this method is exposed, but perhaps it would be better if we can make it private...
this.update = function () {
const offset = new THREE.Vector3();
// so camera.up is the orbit axis
const quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
const quatInverse = quat.clone().invert();
const lastPosition = new THREE.Vector3();
const lastQuaternion = new THREE.Quaternion();
const twoPI = 2 * Math.PI;
return function update() {
const position = scope.object.position;
offset.copy( position ).sub( scope.target );
// rotate offset to "y-axis-is-up" space
offset.applyQuaternion( quat );
// angle from z-axis around y-axis
spherical.setFromVector3( offset );
if ( scope.autoRotate && state === STATE.NONE ) {
rotateLeft( getAutoRotationAngle() );
}
if ( scope.enableDamping ) {
spherical.theta += sphericalDelta.theta * scope.dampingFactor;
spherical.phi += sphericalDelta.phi * scope.dampingFactor;
} else {
spherical.theta += sphericalDelta.theta;
spherical.phi += sphericalDelta.phi;
}
// restrict theta to be between desired limits
let min = scope.minAzimuthAngle;
let max = scope.maxAzimuthAngle;
if ( isFinite( min ) && isFinite( max ) ) {
if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;
if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;
if ( min <= max ) {
spherical.theta = Math.max( min, Math.min( max, spherical.theta ) );
} else {
spherical.theta = spherical.theta > ( min + max ) / 2 ? Math.max( min, spherical.theta ) : Math.min( max, spherical.theta );
}
}
// restrict phi to be between desired limits
spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
spherical.makeSafe();
spherical.radius *= scale;
// restrict radius to be between desired limits
spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
// move target to panned location
if ( scope.enableDamping === true ) {
scope.target.addScaledVector( panOffset, scope.dampingFactor );
} else {
scope.target.add( panOffset );
}
offset.setFromSpherical( spherical );
// rotate offset back to "camera-up-vector-is-up" space
offset.applyQuaternion( quatInverse );
position.copy( scope.target ).add( offset );
scope.object.lookAt( scope.target );
if ( scope.enableDamping === true ) {
sphericalDelta.theta *= 1 - scope.dampingFactor;
sphericalDelta.phi *= 1 - scope.dampingFactor;
panOffset.multiplyScalar( 1 - scope.dampingFactor );
} else {
sphericalDelta.set( 0, 0, 0 );
panOffset.set( 0, 0, 0 );
}
scale = 1;
// update condition is:
// min(camera displacement, camera rotation in radians)^2 > EPS
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
if ( zoomChanged || lastPosition.distanceToSquared( scope.object.position ) > EPS || 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
scope.dispatchEvent( _changeEvent );
lastPosition.copy( scope.object.position );
lastQuaternion.copy( scope.object.quaternion );
zoomChanged = false;
return true;
}
return false;
};
}();
this.dispose = function () {
scope.domElement.removeEventListener( 'contextmenu', onContextMenu );
scope.domElement.removeEventListener( 'pointerdown', onPointerDown );
scope.domElement.removeEventListener( 'pointercancel', onPointerCancel );
scope.domElement.removeEventListener( 'wheel', onMouseWheel );
scope.domElement.removeEventListener( 'pointermove', onPointerMove );
scope.domElement.removeEventListener( 'pointerup', onPointerUp );
if ( scope._domElementKeyEvents !== null ) {
scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
}
//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
};
//
// internals
//
const scope = this;
const STATE = {
NONE: - 1,
ROTATE: 0,
DOLLY: 1,
PAN: 2,
TOUCH_ROTATE: 3,
TOUCH_PAN: 4,
TOUCH_DOLLY_PAN: 5,
TOUCH_DOLLY_ROTATE: 6
};
let state = STATE.NONE;
const EPS = 0.000001;
// current position in spherical coordinates
const spherical = new THREE.Spherical();
const sphericalDelta = new THREE.Spherical();
let scale = 1;
const panOffset = new THREE.Vector3();
let zoomChanged = false;
const rotateStart = new THREE.Vector2();
const rotateEnd = new THREE.Vector2();
const rotateDelta = new THREE.Vector2();
const panStart = new THREE.Vector2();
const panEnd = new THREE.Vector2();
const panDelta = new THREE.Vector2();
const dollyStart = new THREE.Vector2();
const dollyEnd = new THREE.Vector2();
const dollyDelta = new THREE.Vector2();
const pointers = [];
const pointerPositions = {};
function getAutoRotationAngle() {
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
}
function getZoomScale() {
return Math.pow( 0.95, scope.zoomSpeed );
}
function rotateLeft( angle ) {
sphericalDelta.theta -= angle;
}
function rotateUp( angle ) {
sphericalDelta.phi -= angle;
}
const panLeft = function () {
const v = new THREE.Vector3();
return function panLeft( distance, objectMatrix ) {
v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
v.multiplyScalar( - distance );
panOffset.add( v );
};
}();
const panUp = function () {
const v = new THREE.Vector3();
return function panUp( distance, objectMatrix ) {
if ( scope.screenSpacePanning === true ) {
v.setFromMatrixColumn( objectMatrix, 1 );
} else {
v.setFromMatrixColumn( objectMatrix, 0 );
v.crossVectors( scope.object.up, v );
}
v.multiplyScalar( distance );
panOffset.add( v );
};
}();
// deltaX and deltaY are in pixels; right and down are positive
const pan = function () {
const offset = new THREE.Vector3();
return function pan( deltaX, deltaY ) {
const element = scope.domElement;
if ( scope.object.isPerspectiveCamera ) {
// perspective
const position = scope.object.position;
offset.copy( position ).sub( scope.target );
let targetDistance = offset.length();
// half of the fov is center to top of screen
targetDistance *= Math.tan( scope.object.fov / 2 * Math.PI / 180.0 );
// we use only clientHeight here so aspect ratio does not distort speed
panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
} else if ( scope.object.isOrthographicCamera ) {
// orthographic
panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
} else {
// camera neither orthographic nor perspective
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
scope.enablePan = false;
}
};
}();
function dollyOut( dollyScale ) {
if ( scope.object.isPerspectiveCamera ) {
scale /= dollyScale;
} else if ( scope.object.isOrthographicCamera ) {
scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
scope.object.updateProjectionMatrix();
zoomChanged = true;
} else {
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
scope.enableZoom = false;
}
}
function dollyIn( dollyScale ) {
if ( scope.object.isPerspectiveCamera ) {
scale *= dollyScale;
} else if ( scope.object.isOrthographicCamera ) {
scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
scope.object.updateProjectionMatrix();
zoomChanged = true;
} else {
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
scope.enableZoom = false;
}
}
//
// event callbacks - update the object state
//
function handleMouseDownRotate( event ) {
rotateStart.set( event.clientX, event.clientY );
}
function handleMouseDownDolly( event ) {
dollyStart.set( event.clientX, event.clientY );
}
function handleMouseDownPan( event ) {
panStart.set( event.clientX, event.clientY );
}
function handleMouseMoveRotate( event ) {
rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
const element = scope.domElement;
rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height
rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
rotateStart.copy( rotateEnd );
scope.update();
}
function handleMouseMoveDolly( event ) {
dollyEnd.set( event.clientX, event.clientY );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
dollyOut( getZoomScale() );
} else if ( dollyDelta.y < 0 ) {
dollyIn( getZoomScale() );
}
dollyStart.copy( dollyEnd );
scope.update();
}
function handleMouseMovePan( event ) {
panEnd.set( event.clientX, event.clientY );
panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
scope.update();
}
function handleMouseWheel( event ) {
if ( event.deltaY < 0 ) {
dollyIn( getZoomScale() );
} else if ( event.deltaY > 0 ) {
dollyOut( getZoomScale() );
}
scope.update();
}
function handleKeyDown( event ) {
let needsUpdate = false;
switch ( event.code ) {
case scope.keys.UP:
if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
rotateUp( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
} else {
pan( 0, scope.keyPanSpeed );
}
needsUpdate = true;
break;
case scope.keys.BOTTOM:
if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
rotateUp( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
} else {
pan( 0, - scope.keyPanSpeed );
}
needsUpdate = true;
break;
case scope.keys.LEFT:
if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
rotateLeft( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
} else {
pan( scope.keyPanSpeed, 0 );
}
needsUpdate = true;
break;
case scope.keys.RIGHT:
if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
rotateLeft( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
} else {
pan( - scope.keyPanSpeed, 0 );
}
needsUpdate = true;
break;
}
if ( needsUpdate ) {
// prevent the browser from scrolling on cursor keys
event.preventDefault();
scope.update();
}
}
function handleTouchStartRotate() {
if ( pointers.length === 1 ) {
rotateStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );
} else {
const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );
const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );
rotateStart.set( x, y );
}
}
function handleTouchStartPan() {
if ( pointers.length === 1 ) {
panStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );
} else {
const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );
const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );
panStart.set( x, y );
}
}
function handleTouchStartDolly() {
const dx = pointers[ 0 ].pageX - pointers[ 1 ].pageX;
const dy = pointers[ 0 ].pageY - pointers[ 1 ].pageY;
const distance = Math.sqrt( dx * dx + dy * dy );
dollyStart.set( 0, distance );
}
function handleTouchStartDollyPan() {
if ( scope.enableZoom ) handleTouchStartDolly();
if ( scope.enablePan ) handleTouchStartPan();
}
function handleTouchStartDollyRotate() {
if ( scope.enableZoom ) handleTouchStartDolly();
if ( scope.enableRotate ) handleTouchStartRotate();
}
function handleTouchMoveRotate( event ) {
if ( pointers.length == 1 ) {
rotateEnd.set( event.pageX, event.pageY );
} else {
const position = getSecondPointerPosition( event );
const x = 0.5 * ( event.pageX + position.x );
const y = 0.5 * ( event.pageY + position.y );
rotateEnd.set( x, y );
}
rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
const element = scope.domElement;
rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height
rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
rotateStart.copy( rotateEnd );
}
function handleTouchMovePan( event ) {
if ( pointers.length === 1 ) {
panEnd.set( event.pageX, event.pageY );
} else {
const position = getSecondPointerPosition( event );
const x = 0.5 * ( event.pageX + position.x );
const y = 0.5 * ( event.pageY + position.y );
panEnd.set( x, y );
}
panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
}
function handleTouchMoveDolly( event ) {
const position = getSecondPointerPosition( event );
const dx = event.pageX - position.x;
const dy = event.pageY - position.y;
const distance = Math.sqrt( dx * dx + dy * dy );
dollyEnd.set( 0, distance );
dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );
dollyOut( dollyDelta.y );
dollyStart.copy( dollyEnd );
}
function handleTouchMoveDollyPan( event ) {
if ( scope.enableZoom ) handleTouchMoveDolly( event );
if ( scope.enablePan ) handleTouchMovePan( event );
}
function handleTouchMoveDollyRotate( event ) {
if ( scope.enableZoom ) handleTouchMoveDolly( event );
if ( scope.enableRotate ) handleTouchMoveRotate( event );
}
//
// event handlers - FSM: listen for events and reset state
//
function onPointerDown( event ) {
if ( scope.enabled === false ) return;
if ( pointers.length === 0 ) {
scope.domElement.setPointerCapture( event.pointerId );
scope.domElement.addEventListener( 'pointermove', onPointerMove );
scope.domElement.addEventListener( 'pointerup', onPointerUp );
}
//
addPointer( event );
if ( event.pointerType === 'touch' ) {
onTouchStart( event );
} else {
onMouseDown( event );
}
}
function onPointerMove( event ) {
if ( scope.enabled === false ) return;
if ( event.pointerType === 'touch' ) {
onTouchMove( event );
} else {
onMouseMove( event );
}
}
function onPointerUp( event ) {
removePointer( event );
if ( pointers.length === 0 ) {
scope.domElement.releasePointerCapture( event.pointerId );
scope.domElement.removeEventListener( 'pointermove', onPointerMove );
scope.domElement.removeEventListener( 'pointerup', onPointerUp );
}
scope.dispatchEvent( _endEvent );
state = STATE.NONE;
}
function onPointerCancel( event ) {
removePointer( event );
}
function onMouseDown( event ) {
let mouseAction;
switch ( event.button ) {
case 0:
mouseAction = scope.mouseButtons.LEFT;
break;
case 1:
mouseAction = scope.mouseButtons.MIDDLE;
break;
case 2:
mouseAction = scope.mouseButtons.RIGHT;
break;
default:
mouseAction = - 1;
}
switch ( mouseAction ) {
case THREE.MOUSE.DOLLY:
if ( scope.enableZoom === false ) return;
handleMouseDownDolly( event );
state = STATE.DOLLY;
break;
case THREE.MOUSE.ROTATE:
if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
if ( scope.enablePan === false ) return;
handleMouseDownPan( event );
state = STATE.PAN;
} else {
if ( scope.enableRotate === false ) return;
handleMouseDownRotate( event );
state = STATE.ROTATE;
}
break;
case THREE.MOUSE.PAN:
if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
if ( scope.enableRotate === false ) return;
handleMouseDownRotate( event );
state = STATE.ROTATE;
} else {
if ( scope.enablePan === false ) return;
handleMouseDownPan( event );
state = STATE.PAN;
}
break;
default:
state = STATE.NONE;
}
if ( state !== STATE.NONE ) {
scope.dispatchEvent( _startEvent );
}
}
function onMouseMove( event ) {
switch ( state ) {
case STATE.ROTATE:
if ( scope.enableRotate === false ) return;
handleMouseMoveRotate( event );
break;
case STATE.DOLLY:
if ( scope.enableZoom === false ) return;
handleMouseMoveDolly( event );
break;
case STATE.PAN:
if ( scope.enablePan === false ) return;
handleMouseMovePan( event );
break;
}
}
function onMouseWheel( event ) {
if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;
event.preventDefault();
scope.dispatchEvent( _startEvent );
handleMouseWheel( event );
scope.dispatchEvent( _endEvent );
}
function onKeyDown( event ) {
if ( scope.enabled === false || scope.enablePan === false ) return;
handleKeyDown( event );
}
function onTouchStart( event ) {
trackPointer( event );
switch ( pointers.length ) {
case 1:
switch ( scope.touches.ONE ) {
case THREE.TOUCH.ROTATE:
if ( scope.enableRotate === false ) return;
handleTouchStartRotate();
state = STATE.TOUCH_ROTATE;
break;
case THREE.TOUCH.PAN:
if ( scope.enablePan === false ) return;
handleTouchStartPan();
state = STATE.TOUCH_PAN;
break;
default:
state = STATE.NONE;
}
break;
case 2:
switch ( scope.touches.TWO ) {
case THREE.TOUCH.DOLLY_PAN:
if ( scope.enableZoom === false && scope.enablePan === false ) return;
handleTouchStartDollyPan();
state = STATE.TOUCH_DOLLY_PAN;
break;
case THREE.TOUCH.DOLLY_ROTATE:
if ( scope.enableZoom === false && scope.enableRotate === false ) return;
handleTouchStartDollyRotate();
state = STATE.TOUCH_DOLLY_ROTATE;
break;
default:
state = STATE.NONE;
}
break;
default:
state = STATE.NONE;
}
if ( state !== STATE.NONE ) {
scope.dispatchEvent( _startEvent );
}
}
function onTouchMove( event ) {
trackPointer( event );
switch ( state ) {
case STATE.TOUCH_ROTATE:
if ( scope.enableRotate === false ) return;
handleTouchMoveRotate( event );
scope.update();
break;
case STATE.TOUCH_PAN:
if ( scope.enablePan === false ) return;
handleTouchMovePan( event );
scope.update();
break;
case STATE.TOUCH_DOLLY_PAN:
if ( scope.enableZoom === false && scope.enablePan === false ) return;
handleTouchMoveDollyPan( event );
scope.update();
break;
case STATE.TOUCH_DOLLY_ROTATE:
if ( scope.enableZoom === false && scope.enableRotate === false ) return;
handleTouchMoveDollyRotate( event );
scope.update();
break;
default:
state = STATE.NONE;
}
}
function onContextMenu( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
}
function addPointer( event ) {
pointers.push( event );
}
function removePointer( event ) {
delete pointerPositions[ event.pointerId ];
for ( let i = 0; i < pointers.length; i ++ ) {
if ( pointers[ i ].pointerId == event.pointerId ) {
pointers.splice( i, 1 );
return;
}
}
}
function trackPointer( event ) {
let position = pointerPositions[ event.pointerId ];
if ( position === undefined ) {
position = new THREE.Vector2();
pointerPositions[ event.pointerId ] = position;
}
position.set( event.pageX, event.pageY );
}
function getSecondPointerPosition( event ) {
const pointer = event.pointerId === pointers[ 0 ].pointerId ? pointers[ 1 ] : pointers[ 0 ];
return pointerPositions[ pointer.pointerId ];
}
//
scope.domElement.addEventListener( 'contextmenu', onContextMenu );
scope.domElement.addEventListener( 'pointerdown', onPointerDown );
scope.domElement.addEventListener( 'pointercancel', onPointerCancel );
scope.domElement.addEventListener( 'wheel', onMouseWheel, {
passive: false
} );
// force an update at start
this.update();
}
}
// This set of controls performs orbiting, dollying (zooming), and panning.
// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
// This is very similar to OrbitControls, another set of touch behavior
//
// Orbit - right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate
// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
// Pan - left mouse, or arrow keys / touch: one-finger move
class MapControls extends OrbitControls {
constructor( object, domElement ) {
super( object, domElement );
this.screenSpacePanning = false; // pan orthogonal to world-space direction camera.up
this.mouseButtons.LEFT = THREE.MOUSE.PAN;
this.mouseButtons.RIGHT = THREE.MOUSE.ROTATE;
this.touches.ONE = THREE.TOUCH.PAN;
this.touches.TWO = THREE.TOUCH.DOLLY_ROTATE;
}
}
THREE.MapControls = MapControls;
THREE.OrbitControls = OrbitControls;
} )();
</pre>
</div>
</div>
</div>
<script>
$(function(){
$('a[rel*=facebox]').facebox({
'loadingImage': 'https://www.yatex.org/gitbucket/assets/vendors/facebox/loading.gif?20240601154850',
'closeImage': 'https://www.yatex.org/gitbucket/assets/vendors/facebox/closelabel.png?20240601154850'
});
$(document).on("click", ".js-fork-owner-select-target", function() {
var account = $(this).text().replace("@", "");
$("#account").val(account);
$("#fork").submit();
});
});
</script>
</div>
<script>
$(function(){
$(".sidebar-toggle").on('click', function(e){
$.post('https://www.yatex.org/gitbucket/sidebar-collapse', { collapse: !$('body').hasClass('sidebar-collapse') });
});
});
</script>
</body>
</html>
<script>
$(window).on('load', function(){
window.onhashchange = function(){
updateHighlighting();
}
const pre = $('pre.prettyprint');
function updateSourceLineNum() {
$('.source-line-num').remove();
const pos = pre.find('ol.linenums').position();
if (pos) {
$('<div class="source-line-num">').css({
height : pre.height(),
width : '48px',
cursor : 'pointer',
position: 'absolute',
top : pos.top + 'px',
left : pos.left + 'px'
}).click(function(e){
let pos = $(this).data("pos");
if (!pos) {
pos = $('ol.linenums li').map(function(){ return { id: $(this).attr("id"), top: $(this).position().top} }).toArray();
$(this).data("pos",pos);
}
let i = 0;
for(i = 0; i < pos.length - 1; i++){
if(pos[i + 1].top > e.pageY){
break;
}
}
const line = pos[i].id.replace(/^L/,'');
const hash = location.hash;
const baseUrl = location.toString().split("#")[0];
if (e.shiftKey == true && hash.match(/#L\d+(-L\d+)?/)) {
const fragments = hash.split('-');
window.history.pushState('', '', baseUrl + fragments[0] + '-L' + line);
} else {
const p = $("#L" + line).attr('id', '');
window.history.pushState('', '', baseUrl + '#L' + line);
p.attr('id','L' + line);
}
$("#branchCtrlWrapper .btn .muted").text("tree:");
$("#branchCtrlWrapper .btn .strong").text("7a630f0bef");
getSelection().empty();
updateHighlighting();
}).appendTo(pre);
updateHighlighting();
} else {
// Maybe code view is not initialized yet. Retry until succeed.
setTimeout(updateSourceLineNum, 300);
}
}
const repository = $('.blame-action').data('repository');
$('.blame-action').click(function(e){
if(history.pushState && $('pre.prettyprint.no-renderable').length){
e.preventDefault();
history.pushState(null, null, this.href);
updateBlame();
}
});
function updateBlame(){
const m = /\/(blame|blob)(\/.*)$/.exec(location.href);
const mode = m[1];
$('.blame-action').toggleClass("active", mode=='blame').attr('href', repository + (m[1] == 'blame' ? '/blob' : '/blame') + m[2]);
if(pre.parents("div.box-content-bottom").find(".blame").length){
pre.parent().toggleClass("blame-container", mode == 'blame');
updateSourceLineNum();
return;
}
if(mode == 'blob'){
updateSourceLineNum();
return;
}
$(document.body).toggleClass('no-box-shadow', document.body.style.boxShadow === undefined);
$('.blame-action').addClass("active");
const base = $('<div class="blame">').css({height: pre.height()}).prependTo(pre.parents("div.box-content-bottom"));
base.parent().addClass("blame-container");
updateSourceLineNum();
$.get($('.blame-action').data('url')).done(function(data){
let blame = data.blame;
let lastDiv;
const now = new Date().getTime();
const index = [];
for(let i = 0; i < blame.length; i++){
for(let j = 0; j < blame[i].lines.length; j++){
index[blame[i].lines[j]] = blame[i];
}
}
$('pre.prettyprint ol.linenums li').each(function(i, e){
const p = $(e).position();
const h = $(e).height();
if(blame == index[i]){
lastDiv.css("min-height",(p.top + h + 1) - lastDiv.position().top);
} else {
$(e).addClass('blame-sep')
blame = index[i];
const sha = $('<div class="blame-sha">')
.append($('<a>').attr("href", data.root + '/commit/' + blame.id).text(blame.id.substr(0, 7)));
if (blame.prev) {
sha.append($('<br />'))
.append($('<a class="muted-link">').text('prev').attr("href", data.root + '/blame/' + blame.prev + '/' + (blame.prevPath || data.path)));
}
lastDiv = $('<div class="blame-info">')
.addClass('heat' + Math.min(10, Math.max(1, Math.ceil((now - blame.commited) / (24 * 3600 * 1000 * 70)))))
.toggleClass('blame-last', blame.id == data.last)
.data('line', (i + 1))
.css({
"top" : p.top + 'px',
"min-height" : h + 'px'
})
.append(sha)
.append($(blame.avatar).addClass('avatar').css({"float": "left"}))
.append($('<div class="blame-commit-title">').text(blame.message))
.append($('<div class="muted">').html(blame.author + " authed " + blame.authed))
.appendTo(base);
}
});
});
return false;
};
$(document).on('expanded.pushMenu collapsed.pushMenu', function(e){
setTimeout(updateBlame, 300);
});
updateBlame();
});
let scrolling = false;
/**
* Highlight lines which are specified by URL hash.
*/
function updateHighlighting() {
const hash = location.hash;
const isDark = false;
if (hash.match(/#L\d+(-L\d+)?/)) {
if (isDark) {
$('li.highlight-dark').removeClass('highlight-dark');
} else {
$('li.highlight').removeClass('highlight');
}
const fragments = hash.substr(1).split('-');
if (fragments.length == 1) {
if (isDark) {
$('#' + fragments[0]).addClass('highlight-dark');
} else {
$('#' + fragments[0]).addClass('highlight');
}
if(!scrolling){
$(window).scrollTop($('#' + fragments[0]).offset().top);
}
} else if(fragments.length > 1){
const start = parseInt(fragments[0].substr(1));
const end = parseInt(fragments[1].substr(1));
for (let i = start; i <= end; i++) {
if (isDark) {
$('#L' + i).addClass('highlight-dark');
} else {
$('#L' + i).addClass('highlight');
}
}
if (!scrolling) {
$(window).scrollTop($('#' + fragments[0]).offset().top);
}
}
}
scrolling = true;
}
</script>