text:
/*.power-button {
  font-family: sans-serif;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
}
.power-button {
  margin: 0;
}
.power-button article,
.power-button aside,
.power-button details,
.power-button figcaption,
.power-button figure,
.power-button footer,
.power-button header,
.power-button hgroup,
.power-button main,
.power-button menu,
.power-button nav,
.power-button section,
.power-button summary {
  display: block;
}
.power-button audio,
.power-button canvas,
.power-button progress,
.power-button video {
  display: inline-block;
  vertical-align: baseline;
}
.power-button audio:not([controls]) {
  display: none;
  height: 0;
}
.power-button [hidden],
.power-button template {
  display: none;
}
.power-button a {
  background-color: transparent;
}
.power-button a:active,
.power-button a:hover {
  outline: 0;
}
.power-button abbr[title] {
  border-bottom: 1px dotted;
}
.power-button b,
.power-button strong {
  font-weight: bold;
}
.power-button dfn {
  font-style: italic;
}
.power-button h1 {
  font-size: 2em;
  margin: 0.67em 0;
}
.power-button mark {
  background: #ff0;
  color: #000;
}
.power-button small {
  font-size: 80%;
}
.power-button sub,
.power-button sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}
.power-button sup {
  top: -0.5em;
}
.power-button sub {
  bottom: -0.25em;
}
.power-button img {
  border: 0;
}
.power-button svg:not(:root) {
  overflow: hidden;
}
.power-button figure {
  margin: 1em 40px;
}
.power-button hr {
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box;
          box-sizing: content-box;
  height: 0;
}
.power-button pre {
  overflow: auto;
}
.power-button code,
.power-button kbd,
.power-button pre,
.power-button samp {
  font-family: monospace, monospace;
  font-size: 1em;
}
.power-button button,
.power-button input,
.power-button optgroup,
.power-button select,
.power-button textarea {
  color: inherit;
  font: inherit;
  margin: 0;
}
.power-button button {
  overflow: visible;
}
.power-button button,
.power-button select {
  text-transform: none;
}
.power-button button,
.power-buttoninput[type="button"],
.power-button input[type="reset"],
.power-button input[type="submit"] {
  -webkit-appearance: button;
  cursor: pointer;
}
.power-button button[disabled],
.power-buttoninput[disabled] {
  cursor: default;
}
.power-button button::-moz-focus-inner,
.power-button input::-moz-focus-inner {
  border: 0;
  padding: 0;
}
.power-button input {
  line-height: normal;
}
.power-button input[type="checkbox"],
.power-button input[type="radio"] {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  padding: 0;
}
.power-button input[type="number"]::-webkit-inner-spin-button,
.power-button input[type="number"]::-webkit-outer-spin-button {
  height: auto;
}
.power-button input[type="search"] {
  -webkit-appearance: textfield;
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box;
  box-sizing: content-box;
}
.power-button input[type="search"]::-webkit-search-cancel-button,
.power-button input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}
.power-button fieldset {
  border: 1px solid #c0c0c0;
  margin: 0 2px;
  padding: 0.35em 0.625em 0.75em;
}
.power-button legend {
  border: 0;
  padding: 0;
}
.power-button textarea {
  overflow: auto;
}
.power-button optgroup {
  font-weight: bold;
}
.power-button table {
  border-collapse: collapse;
  border-spacing: 0;
}
.power-button td,
.power-button th {
  padding: 0;
}*/
@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('../fonts/glyphicons-halflings-regular.eot');
  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
.power-button .glyphicon {
  position: relative;
  top: 1px;
  display: inline-block;
  font-family: 'Glyphicons Halflings';
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.power-button .glyphicon-asterisk:before {
  content: "\2a";
}
.power-button .glyphicon-plus:before {
  content: "\2b";
}
.power-button .glyphicon-euro:before,
.power-button .glyphicon-eur:before {
  content: "\20ac";
}
.power-button .glyphicon-minus:before {
  content: "\2212";
}
.power-button .glyphicon-cloud:before {
  content: "\2601";
}
.power-button .glyphicon-envelope:before {
  content: "\2709";
}
.power-button .glyphicon-pencil:before {
  content: "\270f";
}
.power-button .glyphicon-glass:before {
  content: "\e001";
}
.power-button .glyphicon-music:before {
  content: "\e002";
}
.power-button .glyphicon-search:before {
  content: "\e003";
}
.power-button .glyphicon-heart:before {
  content: "\e005";
}
.power-button .glyphicon-star:before {
  content: "\e006";
}
.power-button .glyphicon-star-empty:before {
  content: "\e007";
}
.power-button .glyphicon-user:before {
  content: "\e008";
}
.power-button .glyphicon-film:before {
  content: "\e009";
}
.power-button .glyphicon-th-large:before {
  content: "\e010";
}
.power-button .glyphicon-th:before {
  content: "\e011";
}
.power-button .glyphicon-th-list:before {
  content: "\e012";
}
.power-button .glyphicon-ok:before {
  content: "\e013";
}
.power-button .glyphicon-remove:before {
  content: "\e014";
}
.power-button .glyphicon-zoom-in:before {
  content: "\e015";
}
.power-button .glyphicon-zoom-out:before {
  content: "\e016";
}
.power-button .glyphicon-off:before {
  content: "\e017";
}
.power-button .glyphicon-signal:before {
  content: "\e018";
}
.power-button .glyphicon-cog:before {
  content: "\e019";
}
.power-button .glyphicon-trash:before {
  content: "\e020";
}
.power-button .glyphicon-home:before {
  content: "\e021";
}
.power-button .glyphicon-file:before {
  content: "\e022";
}
.power-button .glyphicon-time:before {
  content: "\e023";
}
.power-button .glyphicon-road:before {
  content: "\e024";
}
.power-button .glyphicon-download-alt:before {
  content: "\e025";
}
.power-button .glyphicon-download:before {
  content: "\e026";
}
.power-button .glyphicon-upload:before {
  content: "\e027";
}
.power-button .glyphicon-inbox:before {
  content: "\e028";
}
.power-button .glyphicon-play-circle:before {
  content: "\e029";
}
.power-button .glyphicon-repeat:before {
  content: "\e030";
}
.power-button .glyphicon-refresh:before {
  content: "\e031";
}
.power-button .glyphicon-list-alt:before {
  content: "\e032";
}
.power-button .glyphicon-lock:before {
  content: "\e033";
}
.power-button .glyphicon-flag:before {
  content: "\e034";
}
.power-button .glyphicon-headphones:before {
  content: "\e035";
}
.power-button .glyphicon-volume-off:before {
  content: "\e036";
}
.power-button .glyphicon-volume-down:before {
  content: "\e037";
}
.power-button .glyphicon-volume-up:before {
  content: "\e038";
}
.power-button .glyphicon-qrcode:before {
  content: "\e039";
}
.power-button .glyphicon-barcode:before {
  content: "\e040";
}
.power-button .glyphicon-tag:before {
  content: "\e041";
}
.power-button .glyphicon-tags:before {
  content: "\e042";
}
.power-button .glyphicon-book:before {
  content: "\e043";
}
.power-button .glyphicon-bookmark:before {
  content: "\e044";
}
.power-button .glyphicon-print:before {
  content: "\e045";
}
.power-button .glyphicon-camera:before {
  content: "\e046";
}
.power-button .glyphicon-font:before {
  content: "\e047";
}
.power-button .glyphicon-bold:before {
  content: "\e048";
}
.power-button .glyphicon-italic:before {
  content: "\e049";
}
.power-button .glyphicon-text-height:before {
  content: "\e050";
}
.power-button .glyphicon-text-width:before {
  content: "\e051";
}
.power-button .glyphicon-align-left:before {
  content: "\e052";
}
.power-button .glyphicon-align-center:before {
  content: "\e053";
}
.power-button .glyphicon-align-right:before {
  content: "\e054";
}
.power-button .glyphicon-align-justify:before {
  content: "\e055";
}
.power-button .glyphicon-list:before {
  content: "\e056";
}
.power-button .glyphicon-indent-left:before {
  content: "\e057";
}
.power-button .glyphicon-indent-right:before {
  content: "\e058";
}
.power-button .glyphicon-facetime-video:before {
  content: "\e059";
}
.power-button .glyphicon-picture:before {
  content: "\e060";
}
.power-button .glyphicon-map-marker:before {
  content: "\e062";
}
.power-button .glyphicon-adjust:before {
  content: "\e063";
}
.power-button .glyphicon-tint:before {
  content: "\e064";
}
.power-button .glyphicon-edit:before {
  content: "\e065";
}
.power-button .glyphicon-share:before {
  content: "\e066";
}
.power-button .glyphicon-check:before {
  content: "\e067";
}
.power-button .glyphicon-move:before {
  content: "\e068";
}
.power-button .glyphicon-step-backward:before {
  content: "\e069";
}
.power-button .glyphicon-fast-backward:before {
  content: "\e070";
}
.power-button .glyphicon-backward:before {
  content: "\e071";
}
.power-button .glyphicon-play:before {
  content: "\e072";
}
.power-button .glyphicon-pause:before {
  content: "\e073";
}
.power-button .glyphicon-stop:before {
  content: "\e074";
}
.power-button .glyphicon-forward:before {
  content: "\e075";
}
.power-button .glyphicon-fast-forward:before {
  content: "\e076";
}
.power-button .glyphicon-step-forward:before {
  content: "\e077";
}
.power-button .glyphicon-eject:before {
  content: "\e078";
}
.power-button .glyphicon-chevron-left:before {
  content: "\e079";
}
.power-button .glyphicon-chevron-right:before {
  content: "\e080";
}
.power-button .glyphicon-plus-sign:before {
  content: "\e081";
}
.power-button .glyphicon-minus-sign:before {
  content: "\e082";
}
.power-button .glyphicon-remove-sign:before {
  content: "\e083";
}
.power-button .glyphicon-ok-sign:before {
  content: "\e084";
}
.power-button .glyphicon-question-sign:before {
  content: "\e085";
}
.power-button .glyphicon-info-sign:before {
  content: "\e086";
}
.power-button .glyphicon-screenshot:before {
  content: "\e087";
}
.power-button .glyphicon-remove-circle:before {
  content: "\e088";
}
.power-button .glyphicon-ok-circle:before {
  content: "\e089";
}
.power-button .glyphicon-ban-circle:before {
  content: "\e090";
}
.power-button .glyphicon-arrow-left:before {
  content: "\e091";
}
.power-button .glyphicon-arrow-right:before {
  content: "\e092";
}
.power-button .glyphicon-arrow-up:before {
  content: "\e093";
}
.power-button .glyphicon-arrow-down:before {
  content: "\e094";
}
.power-button .glyphicon-share-alt:before {
  content: "\e095";
}
.power-button .glyphicon-resize-full:before {
  content: "\e096";
}
.power-button .glyphicon-resize-small:before {
  content: "\e097";
}
.power-button .glyphicon-exclamation-sign:before {
  content: "\e101";
}
.power-button .glyphicon-gift:before {
  content: "\e102";
}
.power-button .glyphicon-leaf:before {
  content: "\e103";
}
.power-button .glyphicon-fire:before {
  content: "\e104";
}
.power-button .glyphicon-eye-open:before {
  content: "\e105";
}
.power-button .glyphicon-eye-close:before {
  content: "\e106";
}
.power-button .glyphicon-warning-sign:before {
  content: "\e107";
}
.power-button .glyphicon-plane:before {
  content: "\e108";
}
.power-button .glyphicon-calendar:before {
  content: "\e109";
}
.power-button .glyphicon-random:before {
  content: "\e110";
}
.power-button .glyphicon-comment:before {
  content: "\e111";
}
.power-button .glyphicon-magnet:before {
  content: "\e112";
}
.power-button .glyphicon-chevron-up:before {
  content: "\e113";
}
.power-button .glyphicon-chevron-down:before {
  content: "\e114";
}
.power-button .glyphicon-retweet:before {
  content: "\e115";
}
.power-button .glyphicon-shopping-cart:before {
  content: "\e116";
}
.power-button .glyphicon-folder-close:before {
  content: "\e117";
}
.power-button .glyphicon-folder-open:before {
  content: "\e118";
}
.power-button .glyphicon-resize-vertical:before {
  content: "\e119";
}
.power-button .glyphicon-resize-horizontal:before {
  content: "\e120";
}
.power-button .glyphicon-hdd:before {
  content: "\e121";
}
.power-button .glyphicon-bullhorn:before {
  content: "\e122";
}
.power-button .glyphicon-bell:before {
  content: "\e123";
}
.power-button .glyphicon-certificate:before {
  content: "\e124";
}
.power-button .glyphicon-thumbs-up:before {
  content: "\e125";
}
.power-button .glyphicon-thumbs-down:before {
  content: "\e126";
}
.power-button .glyphicon-hand-right:before {
  content: "\e127";
}
.power-button .glyphicon-hand-left:before {
  content: "\e128";
}
.power-button .glyphicon-hand-up:before {
  content: "\e129";
}
.power-button .glyphicon-hand-down:before {
  content: "\e130";
}
.power-button .glyphicon-circle-arrow-right:before {
  content: "\e131";
}
.power-button .glyphicon-circle-arrow-left:before {
  content: "\e132";
}
.power-button .glyphicon-circle-arrow-up:before {
  content: "\e133";
}
.power-button .glyphicon-circle-arrow-down:before {
  content: "\e134";
}
.power-button .glyphicon-globe:before {
  content: "\e135";
}
.power-button .glyphicon-wrench:before {
  content: "\e136";
}
.power-button .glyphicon-tasks:before {
  content: "\e137";
}
.power-button .glyphicon-filter:before {
  content: "\e138";
}
.power-button .glyphicon-briefcase:before {
  content: "\e139";
}
.power-button .glyphicon-fullscreen:before {
  content: "\e140";
}
.power-button .glyphicon-dashboard:before {
  content: "\e141";
}
.power-button .glyphicon-paperclip:before {
  content: "\e142";
}
.power-button .glyphicon-heart-empty:before {
  content: "\e143";
}
.power-button .glyphicon-link:before {
  content: "\e144";
}
.power-button .glyphicon-phone:before {
  content: "\e145";
}
.power-button .glyphicon-pushpin:before {
  content: "\e146";
}
.power-button .glyphicon-usd:before {
  content: "\e148";
}
.power-button .glyphicon-gbp:before {
  content: "\e149";
}
.power-button .glyphicon-sort:before {
  content: "\e150";
}
.power-button .glyphicon-sort-by-alphabet:before {
  content: "\e151";
}
.power-button .glyphicon-sort-by-alphabet-alt:before {
  content: "\e152";
}
.power-button .glyphicon-sort-by-order:before {
  content: "\e153";
}
.power-button .glyphicon-sort-by-order-alt:before {
  content: "\e154";
}
.power-button .glyphicon-sort-by-attributes:before {
  content: "\e155";
}
.power-button .glyphicon-sort-by-attributes-alt:before {
  content: "\e156";
}
.power-button .glyphicon-unchecked:before {
  content: "\e157";
}
.power-button .glyphicon-expand:before {
  content: "\e158";
}
.power-button .glyphicon-collapse-down:before {
  content: "\e159";
}
.power-button .glyphicon-collapse-up:before {
  content: "\e160";
}
.power-button .glyphicon-log-in:before {
  content: "\e161";
}
.power-button .glyphicon-flash:before {
  content: "\e162";
}
.power-button .glyphicon-log-out:before {
  content: "\e163";
}
.power-button .glyphicon-new-window:before {
  content: "\e164";
}
.power-button .glyphicon-record:before {
  content: "\e165";
}
.power-button .glyphicon-save:before {
  content: "\e166";
}
.power-button .glyphicon-open:before {
  content: "\e167";
}
.power-button .glyphicon-saved:before {
  content: "\e168";
}
.power-button .glyphicon-import:before {
  content: "\e169";
}
.power-button .glyphicon-export:before {
  content: "\e170";
}
.power-button .glyphicon-send:before {
  content: "\e171";
}
.power-button .glyphicon-floppy-disk:before {
  content: "\e172";
}
.power-button .glyphicon-floppy-saved:before {
  content: "\e173";
}
.power-button .glyphicon-floppy-remove:before {
  content: "\e174";
}
.power-button .glyphicon-floppy-save:before {
  content: "\e175";
}
.power-button .glyphicon-floppy-open:before {
  content: "\e176";
}
.power-button .glyphicon-credit-card:before {
  content: "\e177";
}
.power-button .glyphicon-transfer:before {
  content: "\e178";
}
.power-button .glyphicon-cutlery:before {
  content: "\e179";
}
.power-button .glyphicon-header:before {
  content: "\e180";
}
.power-button .glyphicon-compressed:before {
  content: "\e181";
}
.power-button .glyphicon-earphone:before {
  content: "\e182";
}
.power-button .glyphicon-phone-alt:before {
  content: "\e183";
}
.power-button .glyphicon-tower:before {
  content: "\e184";
}
.power-button .glyphicon-stats:before {
  content: "\e185";
}
.power-button .glyphicon-sd-video:before {
  content: "\e186";
}
.power-button .glyphicon-hd-video:before {
  content: "\e187";
}
.power-button .glyphicon-subtitles:before {
  content: "\e188";
}
.power-button .glyphicon-sound-stereo:before {
  content: "\e189";
}
.power-button .glyphicon-sound-dolby:before {
  content: "\e190";
}
.power-button .glyphicon-sound-5-1:before {
  content: "\e191";
}
.power-button .glyphicon-sound-6-1:before {
  content: "\e192";
}
.power-button .glyphicon-sound-7-1:before {
  content: "\e193";
}
.power-button .glyphicon-copyright-mark:before {
  content: "\e194";
}
.power-button .glyphicon-registration-mark:before {
  content: "\e195";
}
.power-button .glyphicon-cloud-download:before {
  content: "\e197";
}
.power-button .glyphicon-cloud-upload:before {
  content: "\e198";
}
.power-button .glyphicon-tree-conifer:before {
  content: "\e199";
}
.power-button .glyphicon-tree-deciduous:before {
  content: "\e200";
}
/*.power-button * {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.power-button *:before,
.power-button *:after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.power-button{
  font-size: 10px;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.power-button {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.42857143;
  color: #333333;
  background-color: #ffffff;
}
.power-button input,
.power-button button,
.power-button select,
.power-button textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}
.power-button a {
  color: #337ab7;
  text-decoration: none;
}
.power-button a:hover,
.power-button a:focus {
  color: #23527c;
  text-decoration: underline;
}
.power-button a:focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
.power-button figure {
  margin: 0;
}
.power-button img {
  vertical-align: middle;
}
.power-button .img-responsive {
  display: block;
  max-width: 100%;
  height: auto;
}
.power-button .img-rounded {
  border-radius: 6px;
}
.power-button .img-thumbnail {
  padding: 4px;
  line-height: 1.42857143;
  background-color: #ffffff;
  border: 1px solid #dddddd;
  border-radius: 4px;
  -webkit-transition: all 0.2s ease-in-out;
  -o-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  display: inline-block;
  max-width: 100%;
  height: auto;
}
.power-button .img-circle {
  border-radius: 50%;
}
.power-button hr {
  margin-top: 20px;
  margin-bottom: 20px;
  border: 0;
  border-top: 1px solid #eeeeee;
}
.power-button .sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
.power-button .sr-only-focusable:active,
.power-button .sr-only-focusable:focus {
  position: static;
  width: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  clip: auto;
}*/
.power-button .btn {
  display: inline-block;
  margin-bottom: 0;
  font-weight: normal;
  text-align: center;
  vertical-align: middle;
  -ms-touch-action: manipulation;
      touch-action: manipulation;
  cursor: pointer;
  background-image: none;
  border: 1px solid transparent;
  white-space: nowrap;
  padding: 6px 12px;
  font-size: 14px;
  line-height: 1.42857143;
  border-radius: 4px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.power-button .btn:focus,
.power-button .btn:active:focus,
.power-button .btn.active:focus,
.power-button .btn.focus,
.power-button .btn:active.focus,
.power-button .btn.active.focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
.power-button .btn:hover,
.power-button .btn:focus,
.power-button .btn.focus {
  color: #333333;
  text-decoration: none;
}
.power-button .btn:active,
.power-button .btn.active {
  outline: 0;
  background-image: none;
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.power-button .btn.disabled,
.power-button .btn[disabled],
.power-button fieldset[disabled] .btn {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.65;
  filter: alpha(opacity=65);
  -webkit-box-shadow: none;
  box-shadow: none;
}
.power-button .btn-default {
  color: #333333;
  background-color: #ffffff;
  border-color: #cccccc;
}
.power-button .btn-default:hover,
.power-button .btn-default:focus,
.power-button .btn-default.focus,
.power-button .btn-default:active,
.power-button .btn-default.active,
.power-button .open > .dropdown-toggle.btn-default {
  color: #333333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.power-button .btn-default:active,
.power-button .btn-default.active,
.power-button .open > .dropdown-toggle.btn-default {
  background-image: none;
}
.power-button .btn-default.disabled,
.power-button .btn-default[disabled],
.power-button fieldset[disabled] .btn-default,
.power-button .btn-default.disabled:hover,
.power-button .btn-default[disabled]:hover,
.power-button fieldset[disabled] .btn-default:hover,
.power-button .btn-default.disabled:focus,
.power-button .btn-default[disabled]:focus,
.power-button fieldset[disabled] .btn-default:focus,
.power-button .btn-default.disabled.focus,
.power-button .btn-default[disabled].focus,
.power-button fieldset[disabled] .btn-default.focus,
.power-button .btn-default.disabled:active,
.power-button .btn-default[disabled]:active,
.power-button fieldset[disabled] .btn-default:active,
.power-button .btn-default.disabled.active,
.power-button .btn-default[disabled].active,
.power-button fieldset[disabled] .btn-default.active {
  background-color: #ffffff;
  border-color: #cccccc;
}
.power-button .btn-default .badge {
  color: #ffffff;
  background-color: #333333;
}
.power-button .btn-primary {
  color: #ffffff;
  background-color: #337ab7;
  border-color: #2e6da4;
}
.power-button .btn-primary:hover,
.power-button .btn-primary:focus,
.power-button .btn-primary.focus,
.power-button .btn-primary:active,
.power-button .btn-primary.active,
.power-button .open > .dropdown-toggle.btn-primary {
  color: #ffffff;
  background-color: #286090;
  border-color: #204d74;
}
.power-button .btn-primary:active,
.power-button .btn-primary.active,
.power-button .open > .dropdown-toggle.btn-primary {
  background-image: none;
}
.power-button .btn-primary.disabled,
.power-button .btn-primary[disabled],
.power-button fieldset[disabled] .btn-primary,
.power-button .btn-primary.disabled:hover,
.power-button .btn-primary[disabled]:hover,
.power-button fieldset[disabled] .btn-primary:hover,
.power-button .btn-primary.disabled:focus,
.power-button .btn-primary[disabled]:focus,
.power-button fieldset[disabled] .btn-primary:focus,
.power-button .btn-primary.disabled.focus,
.power-button .btn-primary[disabled].focus,
.power-button fieldset[disabled] .btn-primary.focus,
.power-button .btn-primary.disabled:active,
.power-button .btn-primary[disabled]:active,
.power-button fieldset[disabled] .btn-primary:active,
.power-button .btn-primary.disabled.active,
.power-button .btn-primary[disabled].active,
.power-button fieldset[disabled] .btn-primary.active {
  background-color: #337ab7;
  border-color: #2e6da4;
}
.power-button .btn-primary .badge {
  color: #337ab7;
  background-color: #ffffff;
}
.power-button .btn-success {
  color: #ffffff;
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.power-button .btn-success:hover,
.power-button .btn-success:focus,
.power-button .btn-success.focus,
.power-button .btn-success:active,
.power-button .btn-success.active,
.power-button .open > .dropdown-toggle.btn-success {
  color: #ffffff;
  background-color: #449d44;
  border-color: #398439;
}
.power-button .btn-success:active,
.power-button .btn-success.active,
.power-button .open > .dropdown-toggle.btn-success {
  background-image: none;
}
.power-button .btn-success.disabled,
.power-button .btn-success[disabled],
.power-button fieldset[disabled] .btn-success,
.power-button .btn-success.disabled:hover,
.power-button .btn-success[disabled]:hover,
.power-button fieldset[disabled] .btn-success:hover,
.power-button .btn-success.disabled:focus,
.power-button .btn-success[disabled]:focus,
.power-button fieldset[disabled] .btn-success:focus,
.power-button .btn-success.disabled.focus,
.power-button .btn-success[disabled].focus,
.power-button fieldset[disabled] .btn-success.focus,
.power-button .btn-success.disabled:active,
.power-button .btn-success[disabled]:active,
.power-button fieldset[disabled] .btn-success:active,
.power-button .btn-success.disabled.active,
.power-button .btn-success[disabled].active,
.power-button fieldset[disabled] .btn-success.active {
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.power-button .btn-success .badge {
  color: #5cb85c;
  background-color: #ffffff;
}
.power-button .btn-info {
  color: #ffffff;
  background-color: #5bc0de;
  border-color: #46b8da;
}
.power-button .btn-info:hover,
.power-button .btn-info:focus,
.power-button .btn-info.focus,
.power-button .btn-info:active,
.power-button .btn-info.active,
.power-button .open > .dropdown-toggle.btn-info {
  color: #ffffff;
  background-color: #31b0d5;
  border-color: #269abc;
}
.power-button .btn-info:active,
.power-button .btn-info.active,
.power-button .open > .dropdown-toggle.btn-info {
  background-image: none;
}
.power-button .btn-info.disabled,
.power-button .btn-info[disabled],
.power-button fieldset[disabled] .btn-info,
.power-button .btn-info.disabled:hover,
.power-button .btn-info[disabled]:hover,
.power-button fieldset[disabled] .btn-info:hover,
.power-button .btn-info.disabled:focus,
.power-button .btn-info[disabled]:focus,
.power-button fieldset[disabled] .btn-info:focus,
.power-button .btn-info.disabled.focus,
.power-button .btn-info[disabled].focus,
.power-button fieldset[disabled] .btn-info.focus,
.power-button .btn-info.disabled:active,
.power-button .btn-info[disabled]:active,
.power-button fieldset[disabled] .btn-info:active,
.power-button .btn-info.disabled.active,
.power-button .btn-info[disabled].active,
.power-button fieldset[disabled] .btn-info.active {
  background-color: #5bc0de;
  border-color: #46b8da;
}
.power-button .btn-info .badge {
  color: #5bc0de;
  background-color: #ffffff;
}
.power-button .btn-warning {
  color: #ffffff;
  background-color: #f0ad4e;
  border-color: #eea236;
}
.power-button .btn-warning:hover,
.power-button .btn-warning:focus,
.power-button .btn-warning.focus,
.power-button .btn-warning:active,
.power-button .btn-warning.active,
.power-button .open > .dropdown-toggle.btn-warning {
  color: #ffffff;
  background-color: #ec971f;
  border-color: #d58512;
}
.power-button .btn-warning:active,
.power-button .btn-warning.active,
.power-button .open > .dropdown-toggle.btn-warning {
  background-image: none;
}
.power-button .btn-warning.disabled,
.power-button .btn-warning[disabled],
.power-button fieldset[disabled] .btn-warning,
.power-button .btn-warning.disabled:hover,
.power-button .btn-warning[disabled]:hover,
.power-button fieldset[disabled] .btn-warning:hover,
.power-button .btn-warning.disabled:focus,
.power-button .btn-warning[disabled]:focus,
.power-button fieldset[disabled] .btn-warning:focus,
.power-button .btn-warning.disabled.focus,
.power-button .btn-warning[disabled].focus,
.power-button fieldset[disabled] .btn-warning.focus,
.power-button .btn-warning.disabled:active,
.power-button .btn-warning[disabled]:active,
.power-button fieldset[disabled] .btn-warning:active,
.power-button .btn-warning.disabled.active,
.power-button .btn-warning[disabled].active,
.power-button fieldset[disabled] .btn-warning.active {
  background-color: #f0ad4e;
  border-color: #eea236;
}
.power-button .btn-warning .badge {
  color: #f0ad4e;
  background-color: #ffffff;
}
.power-button .btn-danger {
  color: #ffffff;
  background-color: #d9534f;
  border-color: #d43f3a;
}
.power-button .btn-danger:hover,
.power-button .btn-danger:focus,
.power-button .btn-danger.focus,
.power-button .btn-danger:active,
.power-button .btn-danger.active,
.power-button .open > .dropdown-toggle.btn-danger {
  color: #ffffff;
  background-color: #c9302c;
  border-color: #ac2925;
}
.power-button .btn-danger:active,
.power-button .btn-danger.active,
.power-button .open > .dropdown-toggle.btn-danger {
  background-image: none;
}
.power-button .btn-danger.disabled,
.power-button .btn-danger[disabled],
.power-button fieldset[disabled] .btn-danger,
.power-button .btn-danger.disabled:hover,
.power-button .btn-danger[disabled]:hover,
.power-button fieldset[disabled] .btn-danger:hover,
.power-button .btn-danger.disabled:focus,
.power-button .btn-danger[disabled]:focus,
.power-button fieldset[disabled] .btn-danger:focus,
.power-button .btn-danger.disabled.focus,
.power-button .btn-danger[disabled].focus,
.power-button fieldset[disabled] .btn-danger.focus,
.power-button .btn-danger.disabled:active,
.power-button .btn-danger[disabled]:active,
.power-button fieldset[disabled] .btn-danger:active,
.power-button .btn-danger.disabled.active,
.power-button .btn-danger[disabled].active,
.power-button fieldset[disabled] .btn-danger.active {
  background-color: #d9534f;
  border-color: #d43f3a;
}
.power-button .btn-danger .badge {
  color: #d9534f;
  background-color: #ffffff;
}
.power-button .btn-link {
  color: #337ab7;
  font-weight: normal;
  border-radius: 0;
}
.power-button .btn-link,
.power-button .btn-link:active,
.power-button .btn-link.active,
.power-button .btn-link[disabled],
.power-button fieldset[disabled] .btn-link {
  background-color: transparent;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.power-button .btn-link,
.power-button .btn-link:hover,
.power-button .btn-link:focus,
.power-button .btn-link:active {
  border-color: transparent;
}
.power-button .btn-link:hover,
.power-button .btn-link:focus {
  color: #23527c;
  text-decoration: underline;
  background-color: transparent;
}
.power-button .btn-link[disabled]:hover,
.power-button fieldset[disabled] .btn-link:hover,
.power-button .btn-link[disabled]:focus,
.power-button fieldset[disabled] .btn-link:focus {
  color: #777777;
  text-decoration: none;
}
.power-button .btn-lg {
  padding: 10px 16px;
  font-size: 18px;
  line-height: 1.33;
  border-radius: 6px;
}
.power-button .btn-sm {
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 3px;
}
.power-button .btn-xs {
  padding: 1px 5px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 3px;
}
.power-button .btn-block {
  display: block;
  width: 100%;
}
.power-button .btn-block + .btn-block {
  margin-top: 5px;
}
.power-button input[type="submit"].btn-block,
.power-button input[type="reset"].btn-block,
.power-button input[type="button"].btn-block {
  width: 100%;
}
.power-button .clearfix:before,
.power-button .clearfix:after {
  content: " ";
  display: table;
}
.power-button .clearfix:after {
  clear: both;
}
.power-button .center-block {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
.power-button .pull-right {
  float: right !important;
}
.power-button .pull-left {
  float: left !important;
}
.power-button .hide {
  display: none !important;
}
.power-button .show {
  display: block !important;
}
.power-button .invisible {
  visibility: hidden;
}
.power-button .text-hide {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}
.power-button .hidden {
  display: none !important;
  visibility: hidden !important;
}
.power-button .affix {
  position: fixed;
}


text:
module EnumStateMachine
  module Integrations #:nodoc:
    module ActiveRecord
      version '2.x - 3.0.x' do
        def self.active?
          ::ActiveRecord::VERSION::MAJOR == 2 || ::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR == 0
        end

        def define_static_state_initializer
          define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
            def attributes_from_column_definition(*)
              result = super
              self.class.state_machines.initialize_states(self, :static => :force, :dynamic => false, :to => result)
              result
            end
          end_eval
        end
      end

      version '2.x' do
        def self.active?
          ::ActiveRecord::VERSION::MAJOR == 2
        end

        def load_locale
          super if defined?(I18n)
        end

        def create_scope(name, scope)
          if owner_class.respond_to?(:named_scope)
            name = name.to_sym
            machine_name = self.name

            # Since ActiveRecord does not allow direct access to the model
            # being used within the evaluation of a dynamic named scope, the
            # scope must be generated manually.  It's necessary to have access
            # to the model so that the state names can be translated to their
            # associated values and so that inheritance is respected properly.
            owner_class.named_scope(name)
            owner_class.scopes[name] = lambda do |model, *states|
              machine_states = model.state_machine(machine_name).states
              values = states.flatten.map {|state| machine_states.fetch(state).value}

              ::ActiveRecord::NamedScope::Scope.new(model, :conditions => scope.call(values))
            end
          end

          # Prevent the Machine class from wrapping the scope
          false
        end

        def invalidate(object, attribute, message, values = [])
          if defined?(I18n)
            super
          else
            object.errors.add(self.attribute(attribute), generate_message(message, values))
          end
        end

        def translate(klass, key, value)
          if defined?(I18n)
            super
          else
            value ? value.to_s.humanize.downcase : 'nil'
          end
        end

        def supports_observers?
          true
        end

        def supports_validations?
          true
        end

        def supports_mass_assignment_security?
          true
        end

        def i18n_scope(klass)
          :activerecord
        end

        def load_observer_extensions
          super
          ::ActiveRecord::Observer.class_eval do
            include EnumStateMachine::Integrations::ActiveModel::Observer
          end unless ::ActiveRecord::Observer < EnumStateMachine::Integrations::ActiveModel::Observer
        end
      end

      version '2.0 - 2.2.x' do
        def self.active?
          ::ActiveRecord::VERSION::MAJOR == 2 && ::ActiveRecord::VERSION::MINOR < 3
        end

        def default_error_message_options(object, attribute, message)
          {:default => @messages[message]}
        end
      end

      version '2.0 - 2.3.1' do
        def self.active?
          ::ActiveRecord::VERSION::MAJOR == 2 && (::ActiveRecord::VERSION::MINOR < 3 || ::ActiveRecord::VERSION::TINY < 2)
        end

        def ancestors_for(klass)
          klass.self_and_descendents_from_active_record
        end
      end

      version '2.3.2 - 2.3.x' do
        def self.active?
          ::ActiveRecord::VERSION::MAJOR == 2 && ::ActiveRecord::VERSION::MINOR == 3 && ::ActiveRecord::VERSION::TINY >= 2
        end

        def ancestors_for(klass)
          klass.self_and_descendants_from_active_record
        end
      end
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
// Looking for PCL_BUILT_WITH_VTK
#include <pcl/pcl_config.h>
#include <pcl/io/image_grabber.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/for_each_type.h>
#include <pcl/io/lzf_image_io.h>
#include <pcl/console/time.h>

#ifdef PCL_BUILT_WITH_VTK
  #include <vtkImageReader2.h>
  #include <vtkImageReader2Factory.h>
  #include <vtkImageData.h>
  #include <vtkSmartPointer.h>
  #include <vtkTIFFReader.h>
  #include <vtkPNGReader.h>
  #include <vtkJPEGReader.h>
  #include <vtkPNMReader.h>
#endif

///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// GrabberImplementation //////////////////////
struct pcl::ImageGrabberBase::ImageGrabberImpl
{
  //! Implementation of ImageGrabber
  ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
                    const std::string& dir,
                    float frames_per_second,
                    bool repeat,
                    bool pclzf_mode=false);
  //! For now, split rgb / depth folders only makes sense for VTK images
  ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
                    const std::string& rgb_dir,
                    const std::string& depth_dir,
                    float frames_per_second,
                    bool repeat);
  ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
                    const std::vector<std::string>& depth_image_files,
                    float frames_per_second,
                    bool repeat);

  void
  trigger ();
  //! Read ahead -- figure out whether we are in VTK image or PCLZF mode
  void
  loadNextCloud ();

  //! Get cloud at a particular location
  bool
  getCloudAt (size_t idx, pcl::PCLPointCloud2 &blob, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
              double &fx, double &fy, double &cx, double &cy) const;

  //! Get cloud at a particular location
  bool
  getCloudVTK (size_t idx, pcl::PCLPointCloud2 &blob, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation) const;
  //! Get cloud at a particular location
  bool
  getCloudPCLZF (size_t idx, pcl::PCLPointCloud2 &blob, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
                 double &fx, double &fy, double &cx, double &cy) const;

  //! Scrapes a directory for image files which contain "rgb" or "depth" and
  //! updates our list accordingly
  void
  loadDepthAndRGBFiles (const std::string &dir);
  //! Scrapes a directory for image files which contain "rgb" or "depth" and
  //! updates our list accordingly
  void
  loadDepthAndRGBFiles (const std::string &depth_dir, const std::string &rgb_dir);
  //! Scrapes a directory for pclzf files which contain "rgb" or "depth and updates
  //  our list accordingly
  void
  loadPCLZFFiles (const std::string &dir);

  //! True if it is an image we know how to read
  bool
  isValidExtension (const std::string &extension);

  //! Convenience function to rewind to the last frame
  void
  rewindOnce ();

  //! Checks if a timestamp is given in the filename
  //! And returns if so
  bool
  getTimestampFromFilepath (const std::string &filepath, uint64_t &timestamp) const;

  size_t
  numFrames () const;

#ifdef PCL_BUILT_WITH_VTK
  //! Load an image file, return the vtkImageReader2, return false if it couldn't be opened
  bool
  getVtkImage (const std::string &filename, vtkSmartPointer<vtkImageData> &image) const;
#endif//PCL_BUILT_WITH_VTK

  pcl::ImageGrabberBase& grabber_;
  float frames_per_second_;
  bool repeat_;
  bool running_;
  // VTK
  std::vector<std::string> depth_image_files_;
  std::vector<std::string> rgb_image_files_;
  // PCLZF
  std::vector<std::string> depth_pclzf_files_;
  std::vector<std::string> rgb_pclzf_files_;
  std::vector<std::string> xml_files_;

  size_t cur_frame_;

  TimeTrigger time_trigger_;

  pcl::PCLPointCloud2 next_cloud_;
  //! Two cases, for depth only and depth+color
  pcl::PointCloud<pcl::PointXYZ> next_cloud_depth_;
  pcl::PointCloud<pcl::PointXYZRGBA> next_cloud_color_;
  Eigen::Vector4f origin_;
  Eigen::Quaternionf orientation_;
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  bool valid_;
  //! Flag to say if a user set the focal length by hand
  //  (so we don't attempt to adjust for QVGA, QQVGA, etc).
  bool pclzf_mode_;

  float depth_image_units_;

  bool manual_intrinsics_;
  double focal_length_x_;
  double focal_length_y_;
  double principal_point_x_;
  double principal_point_y_;

  unsigned int num_threads_;
};

///////////////////////////////////////////////////////////////////////////////////////////
pcl::ImageGrabberBase::ImageGrabberImpl::ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
                                                           const std::string& dir,
                                                           float frames_per_second,
                                                           bool repeat,
                                                           bool pclzf_mode)
  : grabber_ (grabber)
  , frames_per_second_ (frames_per_second)
  , repeat_ (repeat)
  , running_ (false)
  , depth_image_files_ ()
  , rgb_image_files_ ()
  , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&ImageGrabberImpl::trigger, this))
  , next_cloud_ ()
  , origin_ ()
  , orientation_ ()
  , valid_ (false)
  , pclzf_mode_(pclzf_mode)
  , depth_image_units_ (1E-3f)
  , manual_intrinsics_ (false)
  , focal_length_x_ (525.)
  , focal_length_y_ (525.)
  , principal_point_x_ (319.5)
  , principal_point_y_ (239.5)
  , num_threads_ (1)
{
  if(pclzf_mode_)
  {
    loadPCLZFFiles(dir);
  }
  else
  {
    loadDepthAndRGBFiles (dir);
  }
  cur_frame_ = 0;
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::ImageGrabberBase::ImageGrabberImpl::ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
                                                           const std::string& depth_dir,
                                                           const std::string& rgb_dir,
                                                           float frames_per_second,
                                                           bool repeat)
  : grabber_ (grabber)
  , frames_per_second_ (frames_per_second)
  , repeat_ (repeat)
  , running_ (false)
  , depth_image_files_ ()
  , rgb_image_files_ ()
  , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&ImageGrabberImpl::trigger, this))
  , next_cloud_ ()
  , origin_ ()
  , orientation_ ()
  , valid_ (false)
  , pclzf_mode_ (false)
  , depth_image_units_ (1E-3f)
  , manual_intrinsics_ (false)
  , focal_length_x_ (525.)
  , focal_length_y_ (525.)
  , principal_point_x_ (319.5)
  , principal_point_y_ (239.5)
  , num_threads_ (1)
{
  loadDepthAndRGBFiles (depth_dir, rgb_dir);
  cur_frame_ = 0;
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::ImageGrabberBase::ImageGrabberImpl::ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
                                                           const std::vector<std::string>& depth_image_files,
                                                           float frames_per_second,
                                                           bool repeat)
  : grabber_ (grabber)
  , frames_per_second_ (frames_per_second)
  , repeat_ (repeat)
  , running_ (false)
  , depth_image_files_ ()
  , rgb_image_files_ ()
  , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&ImageGrabberImpl::trigger, this))
  , next_cloud_ ()
  , origin_ ()
  , orientation_ ()
  , valid_ (false)
  , pclzf_mode_ (false)
  , depth_image_units_ (1E-3f)
  , manual_intrinsics_ (false)
  , focal_length_x_ (525.)
  , focal_length_y_ (525.)
  , principal_point_x_ (319.5)
  , principal_point_y_ (239.5)
  , num_threads_ (1)
{
  depth_image_files_ = depth_image_files;
  cur_frame_ = 0;
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::ImageGrabberImpl::loadNextCloud ()
{
  if (cur_frame_ >= numFrames ())
  {
    if (repeat_)
      cur_frame_ = 0;
    else
    {
      valid_ = false;
      return;
    }
  }
  valid_ = getCloudAt (cur_frame_, next_cloud_, origin_, orientation_,
      focal_length_x_, focal_length_y_, principal_point_x_, principal_point_y_);
  cur_frame_++;
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::ImageGrabberImpl::trigger ()
{
  if (valid_)
  {
    grabber_.publish (next_cloud_,origin_,orientation_);
  }
  // Preload the next cloud
  loadNextCloud ();
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles (const std::string &dir)
{
  if (!boost::filesystem::exists (dir) || !boost::filesystem::is_directory (dir))
  {
    PCL_ERROR ("[pcl::ImageGrabber::loadDepthAndRGBFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
               " is not a directory: %s", dir.c_str ());
    return;
  }
  std::string pathname;
  std::string extension;
  std::string basename;
  boost::filesystem::directory_iterator end_itr;
  for (boost::filesystem::directory_iterator itr (dir); itr != end_itr; ++itr)
  {
#if BOOST_FILESYSTEM_VERSION == 3
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
    pathname = itr->path ().string ();
    basename = boost::filesystem::basename (itr->path ());
#else
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
    pathname = itr->path ().filename ();
    basename = boost::filesystem::basename (itr->leaf ());
#endif
    if (!boost::filesystem::is_directory (itr->status ())
        && isValidExtension (extension))
    {
      if (basename.find ("rgb") < basename.npos)
      {
        rgb_image_files_.push_back (pathname);
      }
      else if (basename.find ("depth") < basename.npos)
      {
        depth_image_files_.push_back (pathname);
      }
    }
  }
  sort (depth_image_files_.begin (), depth_image_files_.end ());
  if (rgb_image_files_.size () > 0)
    sort (rgb_image_files_.begin (), rgb_image_files_.end ());
}

void
pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles (const std::string &depth_dir, const std::string &rgb_dir)
{
  if (!boost::filesystem::exists (depth_dir) || !boost::filesystem::is_directory (depth_dir))
  {
    PCL_ERROR ("[pcl::ImageGrabber::loadDepthAndRGBFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
               " is not a directory: %s", depth_dir.c_str ());
    return;
  }
  if (!boost::filesystem::exists (rgb_dir) || !boost::filesystem::is_directory (rgb_dir))
  {
    PCL_ERROR ("[pcl::ImageGrabber::loadDepthAndRGBFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
               " is not a directory: %s", rgb_dir.c_str ());
    return;
  }
  std::string pathname;
  std::string extension;
  std::string basename;
  boost::filesystem::directory_iterator end_itr;
  // First iterate over depth images
  for (boost::filesystem::directory_iterator itr (depth_dir); itr != end_itr; ++itr)
  {
#if BOOST_FILESYSTEM_VERSION == 3
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
    pathname = itr->path ().string ();
    basename = boost::filesystem::basename (itr->path ());
#else
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
    pathname = itr->path ().filename ();
    basename = boost::filesystem::basename (itr->leaf ());
#endif
    if (!boost::filesystem::is_directory (itr->status ())
        && isValidExtension (extension))
    {
      if (basename.find ("depth") < basename.npos)
      {
        depth_image_files_.push_back (pathname);
      }
    }
  }
  // Then iterate over RGB images
  for (boost::filesystem::directory_iterator itr (rgb_dir); itr != end_itr; ++itr)
  {
#if BOOST_FILESYSTEM_VERSION == 3
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
    pathname = itr->path ().string ();
    basename = boost::filesystem::basename (itr->path ());
#else
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
    pathname = itr->path ().filename ();
    basename = boost::filesystem::basename (itr->leaf ());
#endif
    if (!boost::filesystem::is_directory (itr->status ())
        && isValidExtension (extension))
    {
      if (basename.find ("rgb") < basename.npos)
      {
        rgb_image_files_.push_back (pathname);
      }
    }
  }
  if (depth_image_files_.size () != rgb_image_files_.size () )
    PCL_WARN ("[pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles] : Watch out not same amount of depth and rgb images");
  if (depth_image_files_.size () > 0)
    sort (depth_image_files_.begin (), depth_image_files_.end ());
  else
    PCL_ERROR ("[pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles] : no depth images added");
  if (rgb_image_files_.size () > 0)
    sort (rgb_image_files_.begin (), rgb_image_files_.end ());
  else
    PCL_ERROR ("[pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles] : no rgb images added");
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::ImageGrabberImpl::loadPCLZFFiles (const std::string &dir)
{
  if (!boost::filesystem::exists (dir) || !boost::filesystem::is_directory (dir))
  {
    PCL_ERROR ("[pcl::ImageGrabber::loadPCLZFFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
               " is not a directory: %s", dir.c_str ());
    return;
  }
  std::string pathname;
  std::string extension;
  std::string basename;
  boost::filesystem::directory_iterator end_itr;
  for (boost::filesystem::directory_iterator itr (dir); itr != end_itr; ++itr)
  {
#if BOOST_FILESYSTEM_VERSION == 3
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
    pathname = itr->path ().string ();
    basename = boost::filesystem::basename (itr->path ());
#else
    extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
    pathname = itr->path ().filename ();
    basename = boost::filesystem::basename (itr->leaf ());
#endif
    if (!boost::filesystem::is_directory (itr->status ())
        && isValidExtension (extension))
    {
      if (basename.find ("rgb") < basename.npos)
        rgb_pclzf_files_.push_back (pathname);
      else if (basename.find ("depth") < basename.npos)
        depth_pclzf_files_.push_back (pathname);
      else
        xml_files_.push_back (pathname);

    }
  }
  sort (depth_pclzf_files_.begin (), depth_pclzf_files_.end ());
  if (rgb_pclzf_files_.size () > 0)
    sort (rgb_pclzf_files_.begin (), rgb_pclzf_files_.end ());
  sort (xml_files_.begin(), xml_files_.end());
  if (depth_pclzf_files_.size() != xml_files_.size())
  {
    PCL_ERROR("[pcl::ImageGrabber::loadPCLZFFiles] # depth clouds != # xml files\n");
    return;
  }
  if (depth_pclzf_files_.size() != rgb_pclzf_files_.size() && rgb_pclzf_files_.size() > 0)
  {
    PCL_ERROR("[pcl::ImageGrabber::loadPCLZFFiles] # depth clouds != # rgb clouds\n");
    return;
  }
}
///////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::ImageGrabberImpl::isValidExtension (const std::string &extension)
{
  bool valid;
  if(pclzf_mode_)
  {
    valid = extension == ".PCLZF" || extension == ".XML";
  }
  else
  {
    valid = extension == ".TIFF" || extension == ".PNG"
         || extension == ".JPG" || extension == ".JPEG"
         || extension == ".PPM";
  }
  return (valid);
}

void
pcl::ImageGrabberBase::ImageGrabberImpl::rewindOnce ()
{
  if (cur_frame_ > 0)
    cur_frame_--;
}

//////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::ImageGrabberImpl::getTimestampFromFilepath (
    const std::string &filepath,
    uint64_t &timestamp) const
{
  // For now, we assume the file is of the form frame_[22-char POSIX timestamp]_*
  char timestamp_str[256];
  int result = std::sscanf (boost::filesystem::basename (filepath).c_str (),
                            "frame_%22s_%*s",
                            timestamp_str);
  if (result > 0)
  {
    // Convert to uint64_t, microseconds since 1970-01-01
    boost::posix_time::ptime cur_date = boost::posix_time::from_iso_string (timestamp_str);
    boost::posix_time::ptime zero_date (
        boost::gregorian::date (1970,boost::gregorian::Jan,1));
    timestamp = (cur_date - zero_date).total_microseconds ();
    return (true);
  }
  return (false);
}

/////////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::ImageGrabberImpl::getCloudAt (size_t idx,
                                                     pcl::PCLPointCloud2 &blob,
                                                     Eigen::Vector4f &origin,
                                                     Eigen::Quaternionf &orientation,
                                                     double &fx,
                                                     double &fy,
                                                     double &cx,
                                                     double &cy) const
{
  if (depth_image_files_.size () > 0)
  {
    fx = focal_length_x_;
    fy = focal_length_y_;
    cx = principal_point_x_;
    cy = principal_point_y_;
    return (getCloudVTK (idx, blob, origin, orientation) );
  }
  else if (depth_pclzf_files_.size () > 0)
    return (getCloudPCLZF (idx, blob, origin, orientation, fx, fy, cx, cy) );
  else
  {
    PCL_ERROR ("[pcl::ImageGrabber::getCloudAt] Could not find VTK or PCLZF files.\n");
    return (false);
  }
}

bool
pcl::ImageGrabberBase::ImageGrabberImpl::getCloudVTK (size_t idx,
                                                      pcl::PCLPointCloud2 &blob,
                                                      Eigen::Vector4f &origin,
                                                      Eigen::Quaternionf &orientation) const
{
#ifdef PCL_BUILT_WITH_VTK
  if (idx > depth_image_files_.size ())
  {
    return (false);
  }
  unsigned short* depth_pixel;
  unsigned char* color_pixel;
  vtkSmartPointer<vtkImageData> depth_image;
  vtkSmartPointer<vtkImageData> rgb_image;
  const std::string &depth_image_file = depth_image_files_[idx];
  // If there are RGB files, load an rgb image
  if (rgb_image_files_.size () != 0)
  {
    const std::string &rgb_image_file = rgb_image_files_[idx];
    // If we were unable to pull a Vtk image, throw an error
    if (!getVtkImage (rgb_image_file, rgb_image) )
    {
      return (false);
    }
  }
  if (!getVtkImage (depth_image_file, depth_image) )
  {
    return (false);
  }
  int* dims = depth_image->GetDimensions ();

  // Fill in image data
  depth_pixel = static_cast<unsigned short*>(depth_image->GetScalarPointer ());

  // Set up intrinsics
  float scaleFactorX, scaleFactorY;
  float centerX, centerY;
  if (manual_intrinsics_)
  {
    scaleFactorX = 1.f / static_cast<float> (focal_length_x_);
    scaleFactorY = 1.f / static_cast<float> (focal_length_y_);
    centerX = static_cast<float> (principal_point_x_);
    centerY = static_cast<float> (principal_point_y_);
  }
  else
  {
    // The 525 factor default is only true for VGA. If not, we should scale
    scaleFactorX = scaleFactorY = 1/525.f * 640.f / static_cast<float> (dims[0]);
    centerX = ((float)dims[0] - 1.f)/2.f;
    centerY = ((float)dims[1] - 1.f)/2.f;
  }

  if(rgb_image_files_.size() > 0)
  {
    pcl::PointCloud<pcl::PointXYZRGBA> cloud_color;
    cloud_color.width = dims[0];
    cloud_color.height = dims[1];
    cloud_color.is_dense = false;
    cloud_color.points.resize (depth_image->GetNumberOfPoints ());

    for (int y = 0; y < dims[1]; ++y)
    {
      for (int x = 0; x < dims[0]; ++x, ++depth_pixel)
      {
        pcl::PointXYZRGBA &pt = cloud_color.at (x,y);
        float depth = static_cast<float> (*depth_pixel) * depth_image_units_;
        if (depth == 0.0f)
          pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN ();
        else
        {
          pt.x = (static_cast<float> (x) - centerX) * scaleFactorX * depth;
          pt.y = (static_cast<float> (y) - centerY) * scaleFactorY * depth;
          pt.z = depth;
        }

        color_pixel = reinterpret_cast<unsigned char*> (rgb_image->GetScalarPointer (x, y, 0));
        pt.r = color_pixel[0];
        pt.g = color_pixel[1];
        pt.b = color_pixel[2];
      }
    }
    // Handle timestamps
    uint64_t timestamp;
    if (getTimestampFromFilepath (depth_image_file, timestamp))
    {
      cloud_color.header.stamp = timestamp;
    }

    pcl::toPCLPointCloud2 (cloud_color, blob);
  }
  else
  {
    pcl::PointCloud<pcl::PointXYZ> cloud;
    cloud.width = dims[0];
    cloud.height = dims[1];
    cloud.is_dense = false;
    cloud.points.resize (depth_image->GetNumberOfPoints ());
    for (int y = 0; y < dims[1]; ++y)
    {
      for (int x = 0; x < dims[0]; ++x, ++depth_pixel)
      {
        pcl::PointXYZ &pt = cloud.at (x,y);
        float depth = static_cast<float> (*depth_pixel) * depth_image_units_;
        if (depth == 0.0f)
          pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN ();
        else
        {
          pt.x = ((float)x - centerX) * scaleFactorX * depth;
          pt.y = ((float)y - centerY) * scaleFactorY * depth;
          pt.z = depth;
        }
      }
    }
    // Handle timestamps
    uint64_t timestamp;
    if (getTimestampFromFilepath (depth_image_file, timestamp))
    {
      cloud.header.stamp = timestamp;
    }

    pcl::toPCLPointCloud2 (cloud, blob);
  }
  // Origin 0, orientation is forward
  origin = Eigen::Vector4f::Zero ();
  orientation = Eigen::Quaternionf::Identity ();

  return (true);
#else
    PCL_ERROR ("[pcl::ImageGrabber::loadNextCloudVTK] Attempted to read image files, but PCL was not built with VTK [no -DPCL_BUILT_WITH_VTK]. \n");
    return (false);
#endif //PCL_BUILT_WITH_VTK

}

bool
pcl::ImageGrabberBase::ImageGrabberImpl::getCloudPCLZF (size_t idx,
                                                        pcl::PCLPointCloud2 &blob,
                                                        Eigen::Vector4f &origin,
                                                        Eigen::Quaternionf &orientation,
                                                        double &fx,
                                                        double &fy,
                                                        double &cx,
                                                        double &cy) const
{
  if (idx > depth_pclzf_files_.size ())
  {
    return (false);
  }
  // Get the proper files
  const std::string &depth_pclzf_file = depth_pclzf_files_[idx];
  const std::string &xml_file = xml_files_[idx];
  if (rgb_pclzf_files_.size () > 0)
  {
    pcl::PointCloud<pcl::PointXYZRGBA> cloud_color;
    const std::string &rgb_pclzf_file = rgb_pclzf_files_[idx];
    pcl::io::LZFRGB24ImageReader rgb;
    pcl::io::LZFBayer8ImageReader bayer;
    pcl::io::LZFYUV422ImageReader yuv;
    pcl::io::LZFDepth16ImageReader depth;
    if (manual_intrinsics_)
    {
      pcl::io::CameraParameters manual_params;
      manual_params.focal_length_x = focal_length_x_;
      manual_params.focal_length_y = focal_length_y_;
      manual_params.principal_point_x = principal_point_x_;
      manual_params.principal_point_y = principal_point_y_;
      fx = focal_length_x_;
      fy = focal_length_y_;
      cx = principal_point_x_;
      cy = principal_point_y_;
      rgb.setParameters (manual_params);
      yuv.setParameters (manual_params);
      bayer.setParameters (manual_params);
      depth.setParameters (manual_params);
    }
    else
    {
      rgb.readParameters (xml_file);
      yuv.readParameters (xml_file);
      bayer.readParameters (xml_file);
      depth.readParameters (xml_file);
      // update intrinsics
      pcl::io::CameraParameters loaded_params = depth.getParameters ();
      // Set intrinsics so we can update our estimate, if necessary
      fx = loaded_params.focal_length_x;
      fy = loaded_params.focal_length_y;
      cx = loaded_params.principal_point_x;
      cy = loaded_params.principal_point_y;
    }
    cloud_color.is_dense = false;
    if (num_threads_ == 1)
    {
      if (!rgb.read (rgb_pclzf_file, cloud_color))
        if (!yuv.read (rgb_pclzf_file, cloud_color))
          bayer.read (rgb_pclzf_file, cloud_color);
      depth.read (depth_pclzf_file, cloud_color);
    }
    else
    {
      if (!rgb.read (rgb_pclzf_file, cloud_color))
        if (!yuv.readOMP (rgb_pclzf_file, cloud_color, num_threads_)) // Only YUV speeds up currently
          bayer.read (rgb_pclzf_file, cloud_color);
      depth.readOMP (depth_pclzf_file, cloud_color, num_threads_);
    }
    // handle timestamps
    uint64_t timestamp;
    if (getTimestampFromFilepath (depth_pclzf_file, timestamp))
    {
      cloud_color.header.stamp = timestamp;
    }
    pcl::toPCLPointCloud2 (cloud_color, blob);
  }
  else
  {
    pcl::PointCloud<pcl::PointXYZ> cloud;
    pcl::io::LZFDepth16ImageReader depth;
    if (manual_intrinsics_)
    {
      pcl::io::CameraParameters manual_params;
      manual_params.focal_length_x = focal_length_x_;
      manual_params.focal_length_y = focal_length_y_;
      manual_params.principal_point_x = principal_point_x_;
      manual_params.principal_point_y = principal_point_y_;
      // Set intrinsics so we can update our estimate, if necessary
      fx = focal_length_x_;
      fy = focal_length_y_;
      cx = principal_point_x_;
      cy = principal_point_y_;
      depth.setParameters (manual_params);
    }
    else
    {
      depth.readParameters (xml_file);
      // update intrinsics
      pcl::io::CameraParameters loaded_params = depth.getParameters ();
      fx = loaded_params.focal_length_x;
      fy = loaded_params.focal_length_y;
      cx = loaded_params.principal_point_x;
      cy = loaded_params.principal_point_y;
    }
    cloud.is_dense = false;
    if (num_threads_ == 1)
      depth.read (depth_pclzf_file, cloud);
    else
      depth.readOMP (depth_pclzf_file, cloud, num_threads_);
    // handle timestamps
    uint64_t timestamp;
    if (getTimestampFromFilepath (depth_pclzf_file, timestamp))
    {
      cloud.header.stamp = timestamp;
    }
    pcl::toPCLPointCloud2 (cloud, blob);
  }

  // Origin 0, orientation is forward
  origin = Eigen::Vector4f::Zero ();
  orientation = Eigen::Quaternionf::Identity ();
  return (true);
}

////////////////////////////////////////////////////////////////////////
//
#ifdef PCL_BUILT_WITH_VTK
bool
pcl::ImageGrabberBase::ImageGrabberImpl::getVtkImage (
    const std::string &filename,
    vtkSmartPointer<vtkImageData> &image) const
{

  vtkSmartPointer<vtkImageReader2> reader;
  // Check extension to generate the proper reader
  int retval;
  std::string upper = boost::algorithm::to_upper_copy (filename);
  if (upper.find (".TIFF") < upper.npos)
  {
    vtkSmartPointer<vtkTIFFReader> tiff_reader = vtkSmartPointer<vtkTIFFReader>::New ();
    retval = tiff_reader->CanReadFile (filename.c_str ());
    reader = tiff_reader;
  }
  else if (upper.find (".PNG") < upper.npos)
  {
    vtkSmartPointer<vtkPNGReader> png_reader = vtkSmartPointer<vtkPNGReader>::New ();
    retval = png_reader->CanReadFile (filename.c_str ());
    reader = png_reader;
  }
  else if (upper.find (".JPG") < upper.npos || upper.find (".JPEG") < upper.npos)
  {
    vtkSmartPointer<vtkJPEGReader> jpg_reader = vtkSmartPointer<vtkJPEGReader>::New ();
    retval = jpg_reader->CanReadFile (filename.c_str ());
    reader = jpg_reader;
  }
  else if (upper.find (".PPM") < upper.npos)
  {
    vtkSmartPointer<vtkPNMReader> ppm_reader = vtkSmartPointer<vtkPNMReader>::New ();
    retval = ppm_reader->CanReadFile (filename.c_str ());
    reader = ppm_reader;
  }
  else
  {
    PCL_ERROR ("[pcl::ImageGrabber::getVtkImage] Attempted to access an invalid filetype: %s\n", filename.c_str ());
    return (false);
  }
  if (retval == 0)
  {
    PCL_ERROR ("[pcl::ImageGrabber::getVtkImage] Image file can't be read: %s\n", filename.c_str ());
    return (false);
  }
  else if (retval == 1)
  {
    PCL_ERROR ("[pcl::ImageGrabber::getVtkImage] Can't prove that I can read: %s\n", filename.c_str ());
    return (false);
  }
  reader->SetFileName (filename.c_str ());
  reader->Update ();
  image = reader->GetOutput ();
  return (true);
}
#endif //PCL_BUILT_WITH_VTK

///////////////////////////////////////////////////////////////////////////////////////////
size_t
pcl::ImageGrabberBase::ImageGrabberImpl::numFrames () const
{
  if (pclzf_mode_)
    return (depth_pclzf_files_.size ());
  else
    return (depth_image_files_.size ());
}

//////////////////////// GrabberBase //////////////////////
pcl::ImageGrabberBase::ImageGrabberBase (const std::string& directory, float frames_per_second, bool repeat, bool pclzf_mode)
  : impl_ (new ImageGrabberImpl (*this, directory, frames_per_second, repeat, pclzf_mode))
{
}

//////////////////////////////////////////////////////////
pcl::ImageGrabberBase::ImageGrabberBase (const std::string& rgb_dir, const std::string &depth_dir, float frames_per_second, bool repeat)
  : impl_ (new ImageGrabberImpl (*this, rgb_dir, depth_dir, frames_per_second, repeat))
{
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::ImageGrabberBase::ImageGrabberBase (const std::vector<std::string>& depth_image_files, float frames_per_second, bool repeat)
  : impl_ (new ImageGrabberImpl (*this, depth_image_files, frames_per_second, repeat))
{
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::ImageGrabberBase::~ImageGrabberBase () throw ()
{
  stop ();
  delete impl_;
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::start ()
{
  if (impl_->frames_per_second_ > 0)
  {
    impl_->running_ = true;
    impl_->time_trigger_.start ();
  }
  else // manual trigger to preload the first cloud
    impl_->trigger ();
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::stop ()
{
  if (impl_->frames_per_second_ > 0)
  {
    impl_->time_trigger_.stop ();
    impl_->running_ = false;
  }
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::trigger ()
{
  if (impl_->frames_per_second_ > 0)
    return;
  impl_->trigger ();
}

///////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::isRunning () const
{
  return (impl_->running_);
}

///////////////////////////////////////////////////////////////////////////////////////////
std::string
pcl::ImageGrabberBase::getName () const
{
  return ("ImageGrabber");
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::rewind ()
{
  impl_->cur_frame_ = 0;
}

///////////////////////////////////////////////////////////////////////////////////////////
float
pcl::ImageGrabberBase::getFramesPerSecond () const
{
  return (impl_->frames_per_second_);
}

///////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::isRepeatOn () const
{
  return (impl_->repeat_);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::setRGBImageFiles (const std::vector<std::string>& rgb_image_files)
{
  impl_->rgb_image_files_ = rgb_image_files;
  impl_->cur_frame_ = 0;
}

///////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::setCameraIntrinsics (const double focal_length_x,
                                            const double focal_length_y,
                                            const double principal_point_x,
                                            const double principal_point_y)
{
  impl_->focal_length_x_ = focal_length_x;
  impl_->focal_length_y_ = focal_length_y;
  impl_->principal_point_x_ = principal_point_x;
  impl_->principal_point_y_ = principal_point_y;
  impl_->manual_intrinsics_ = true;
  // If we've already preloaded a valid cloud, we need to recompute it
  if (impl_->valid_)
  {
    impl_->rewindOnce ();
    impl_->loadNextCloud ();
  }
}

void
pcl::ImageGrabberBase::getCameraIntrinsics (double &focal_length_x,
                                            double &focal_length_y,
                                            double &principal_point_x,
                                            double &principal_point_y) const
{
  focal_length_x = impl_->focal_length_x_;
  focal_length_y = impl_->focal_length_y_;
  principal_point_x = impl_->principal_point_x_;
  principal_point_y = impl_->principal_point_y_;
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::setDepthImageUnits (const float units)
{
  impl_->depth_image_units_ = units;
}
///////////////////////////////////////////////////////////////////////////////////////////
size_t
pcl::ImageGrabberBase::numFrames () const
{
  return (impl_->numFrames ());
}

//////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::getCloudAt (size_t idx,
                                   pcl::PCLPointCloud2 &blob,
                                   Eigen::Vector4f &origin,
                                   Eigen::Quaternionf &orientation) const
{
  double fx, fy, cx, cy;
  return (impl_->getCloudAt (idx, blob, origin, orientation, fx, fy, cx, cy));
}

//////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::atLastFrame () const
{
  if (impl_->cur_frame_ == numFrames () - 1)
    return (true);
  else
    return (false);
}

//////////////////////////////////////////////////////////////////////////////////////////
std::string
pcl::ImageGrabberBase::getCurrentDepthFileName () const
{
  std::string pathname;
  if (impl_->pclzf_mode_)
    pathname = impl_->depth_pclzf_files_[impl_->cur_frame_];
  else
    pathname = impl_->depth_image_files_[impl_->cur_frame_];
  std::string basename = boost::filesystem::basename (pathname);
  return (basename);
}
//////////////////////////////////////////////////////////////////////////////////////////
std::string
pcl::ImageGrabberBase::getPrevDepthFileName () const
{
  std::string pathname;
  if (impl_->pclzf_mode_)
    pathname = impl_->depth_pclzf_files_[impl_->cur_frame_-1];
  else
    pathname = impl_->depth_image_files_[impl_->cur_frame_-1];
  std::string basename = boost::filesystem::basename (pathname);
  return (basename);
}

/////////////////////////////////////////////////////////////////////////////////////////
std::string
pcl::ImageGrabberBase::getDepthFileNameAtIndex (size_t idx) const
{
  std::string pathname;
  if (impl_->pclzf_mode_)
    pathname = impl_->depth_pclzf_files_[idx];
  else
    pathname = impl_->depth_image_files_[idx];
  std::string basename = boost::filesystem::basename (pathname);
  return (basename);
}

////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::ImageGrabberBase::getTimestampAtIndex (size_t idx, uint64_t &timestamp) const
{
  std::string filename;
  if (impl_->pclzf_mode_)
    filename = impl_->depth_pclzf_files_[idx];
  else
    filename = impl_->depth_image_files_[idx];
  return (impl_->getTimestampFromFilepath (filename, timestamp));
}

////////////////////////////////////////////////////////////////////////////////////////
void
pcl::ImageGrabberBase::setNumberOfThreads (unsigned int nr_threads)
{
  impl_->num_threads_ = nr_threads;
}


text:
package org.apache.solr.update.processor;

import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.component.RealTimeGetComponent;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.update.AddUpdateCommand;
import org.apache.solr.update.DeleteUpdateCommand;
import org.apache.solr.update.UpdateCommand;
import org.apache.solr.update.VersionInfo;
import org.apache.solr.util.RefCounted;
import org.apache.solr.util.plugin.SolrCoreAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Map;

import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST;
import static org.apache.solr.common.SolrException.ErrorCode.CONFLICT;
import static org.apache.solr.common.SolrException.ErrorCode.SERVER_ERROR;
import static org.apache.solr.update.processor.DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM;

/**
 *

 * This Factory generates an UpdateProcessor that helps to enforce Version
 * constraints on documents based on per-document version numbers using a configured
 * name of a versionField.  It should be configured on the "default"
 * update processor somewhere before the DistributedUpdateProcessorFactory.
 * As an example, see the solrconfig.xml that the tests use:
 * solr/core/src/test-files/solr/collection1/conf/solrconfig-externalversionconstraint.xml
 *

 *

 * When documents are added through this processor, if a document with the same
 * unique key already exists in the collection, then the value of the
 * versionField in the existing document is not less then the
 * field value in the new document then the new document is rejected with a
 * 409 Version Conflict error.
 *

 *

 * In addition to the mandatory versionField init param, two additional
 * optional init params affect the behavior of this factory:
 *

 *

 *
deleteVersionParam - This string parameter controls whether this
 *     processor will intercept and inspect Delete By Id commands in addition to adding
 *     documents.  If specified, then the value will specify the name of a request
 *     paramater which becomes  mandatory for all Delete By Id commands.  This param
 *     must then be used to specify the document version associated with the delete.
 *     If the version specified using this param is not greater then the value in the
 *     versionField for any existing document, then the delete will fail
 *     with a 409 Version Conflict error.  When using this param, Any Delete By Id
 *     command with a high enough document version number to succeed will be internally
 *     converted into an Add Document command that replaces the existing document with
 *     a new one which is empty except for the Unique Key and versionField
 *     to keeping a record of the deleted version so future Add Document commands will
 *     fail if their "new" version is not high enough.

 *
 *
ignoreOldUpdates - This boolean parameter defaults to
 *     false, but if set to true causes any update with a
 *     document version that is not great enough to be silently ignored (and return
 *     a status 200 to the client) instead of generating a 409 Version Conflict error.
 *

 *

 */
public class DocBasedVersionConstraintsProcessorFactory extends UpdateRequestProcessorFactory implements SolrCoreAware, UpdateRequestProcessorFactory.RunAlways {
  public final static Logger log = LoggerFactory.getLogger(DocBasedVersionConstraintsProcessorFactory.class);

  private boolean ignoreOldUpdates = false;
  private String versionField = null;
  private String deleteVersionParamName = null;
  private boolean useFieldCache;

  @Override
  public void init( NamedList args )  {

    Object tmp = args.remove("versionField");
    if (null == tmp) {
      throw new SolrException(SERVER_ERROR,
                              "'versionField' must be configured");
    }
    if (! (tmp instanceof String) ) {
      throw new SolrException(SERVER_ERROR,
                              "'versionField' must be configured as a <str>");
    }
    versionField = tmp.toString();

    // optional
    tmp = args.remove("deleteVersionParam");
    if (null != tmp) {
      if (! (tmp instanceof String) ) {
        throw new SolrException(SERVER_ERROR,
                                "'deleteVersionParam' must be configured as a <str>");
      }
      deleteVersionParamName = tmp.toString();
    }

    // optional - defaults to false
    tmp = args.remove("ignoreOldUpdates");
    if (null != tmp) {
      if (! (tmp instanceof Boolean) ) {
        throw new SolrException(SERVER_ERROR,
                                "'ignoreOldUpdates' must be configured as a <bool>");
      }
      ignoreOldUpdates = ((Boolean)tmp).booleanValue();
    }
    super.init(args);
  }

  public UpdateRequestProcessor getInstance(SolrQueryRequest req,
                                            SolrQueryResponse rsp,
                                            UpdateRequestProcessor next ) {
    return new DocBasedVersionConstraintsProcessor(versionField,
                                                   ignoreOldUpdates,
                                                   deleteVersionParamName,
                                                   useFieldCache,
                                                   req, rsp, next);
  }

  @Override
  public void inform(SolrCore core) {

    if (core.getUpdateHandler().getUpdateLog() == null) {
      throw new SolrException(SERVER_ERROR,
          "updateLog must be enabled.");
    }

    if (core.getLatestSchema().getUniqueKeyField() == null) {
      throw new SolrException(SERVER_ERROR,
          "schema must have uniqueKey defined.");
    }

    SchemaField userVersionField = core.getLatestSchema().getField(versionField);
    if (userVersionField == null || !userVersionField.stored() || userVersionField.multiValued()) {
      throw new SolrException(SERVER_ERROR,
          "field " + versionField + " must be defined in schema, be stored, and be single valued.");
    }

    try {
      ValueSource vs = userVersionField.getType().getValueSource(userVersionField, null);
      useFieldCache = true;
    } catch (Exception e) {
      log.warn("Can't use fieldcache/valuesource: " + e.getMessage());
    }
  }

  private static class DocBasedVersionConstraintsProcessor
    extends UpdateRequestProcessor {

    private final String versionFieldName;
    private final SchemaField userVersionField;
    private final SchemaField solrVersionField;
    private final boolean ignoreOldUpdates;
    private final String deleteVersionParamName;
    private final SolrCore core;

    private long oldSolrVersion;  // current _version_ of the doc in the index/update log
    private DistributedUpdateProcessor distribProc;  // the distributed update processor following us
    private DistributedUpdateProcessor.DistribPhase phase;
    private boolean useFieldCache;

    public DocBasedVersionConstraintsProcessor(String versionField,
                                               boolean ignoreOldUpdates,
                                               String deleteVersionParamName,
                                               boolean useFieldCache,
                                               SolrQueryRequest req,
                                               SolrQueryResponse rsp,
                                               UpdateRequestProcessor next ) {
      super(next);
      this.ignoreOldUpdates = ignoreOldUpdates;
      this.deleteVersionParamName = deleteVersionParamName;
      this.core = req.getCore();
      this.versionFieldName = versionField;
      this.userVersionField = core.getLatestSchema().getField(versionField);
      this.solrVersionField = core.getLatestSchema().getField(VersionInfo.VERSION_FIELD);
      this.useFieldCache = useFieldCache;

      for (UpdateRequestProcessor proc = next ;proc != null; proc = proc.next) {
        if (proc instanceof DistributedUpdateProcessor) {
          distribProc = (DistributedUpdateProcessor)proc;
          break;
        }
      }

      if (distribProc == null) {
        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "DistributedUpdateProcessor must follow DocBasedVersionConstraintsProcessor");
      }

      phase = DistributedUpdateProcessor.DistribPhase.parseParam(req.getParams().get(DISTRIB_UPDATE_PARAM));

    }

    /**
     * Inspects a raw field value (which may come from a doc in the index, or a
     * doc in the UpdateLog that still has String values, or a String sent by
     * the user as a param) and if it is a String, asks the versionField FieldType
     * to convert it to an Object suitable for comparison.
     */
    private Object convertFieldValueUsingType(SchemaField sf, final Object rawValue) {
      if (rawValue instanceof CharSequence) {
        // in theory, the FieldType might still be CharSequence based,
        // but in that case trust it to do an identiy conversion...
        FieldType fieldType = userVersionField.getType();
        BytesRefBuilder term = new BytesRefBuilder();
        fieldType.readableToIndexed((CharSequence)rawValue, term);
        return fieldType.toObject(userVersionField, term.get());
      }
      // else...
      return rawValue;
    }

    /**
     * Returns true if the specified new version value is greater the the one
     * already known to exist for the document, or the document does not already
     * exist.
     * Returns false if the specified new version is not high enough but the
     * processor has been configured with ignoreOldUpdates=true
     * Throws a SolrException if the version is not high enough and
     * ignoreOldUpdates=false
     */
    private boolean isVersionNewEnough(BytesRef indexedDocId,
                                       Object newUserVersion) throws IOException {
      assert null != indexedDocId;
      assert null != newUserVersion;

      oldSolrVersion = -1;
      // log.info("!!!!!!!!! isVersionNewEnough being called for " + indexedDocId.utf8ToString() + " newVersion=" + newUserVersion);
      newUserVersion = convertFieldValueUsingType(userVersionField, newUserVersion);
      Object oldUserVersion = null;
      SolrInputDocument oldDoc = null;

      if (useFieldCache) {
        oldDoc = RealTimeGetComponent.getInputDocumentFromTlog(core, indexedDocId);
        if (oldDoc == RealTimeGetComponent.DELETED) {
          return true;
        }
        if (oldDoc == null) {
          // need to look up in index now...
          RefCounted<SolrIndexSearcher> newestSearcher = core.getRealtimeSearcher();
          try {
            SolrIndexSearcher searcher = newestSearcher.get();
            long lookup = searcher.lookupId(indexedDocId);
            if (lookup < 0) {
              // doc not in index either...
              return true;
            }

            ValueSource vs = solrVersionField.getType().getValueSource(solrVersionField, null);
            Map context = ValueSource.newContext(searcher);
            vs.createWeight(context, searcher);
            FunctionValues fv = vs.getValues(context, searcher.getTopReaderContext().leaves().get((int)(lookup>>32)));
            oldSolrVersion = fv.longVal((int)lookup);

            vs = userVersionField.getType().getValueSource(userVersionField, null);
            context = ValueSource.newContext(searcher);
            vs.createWeight(context, searcher);
            fv = vs.getValues(context, searcher.getTopReaderContext().leaves().get((int)(lookup>>32)));
            oldUserVersion = fv.objectVal((int)lookup);

          } catch (IOException e) {
            throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error reading version from index", e);
          } finally {
            if (newestSearcher != null) {
              newestSearcher.decref();
            }
          }
        }
      } else {
        // stored fields only...

        oldDoc = RealTimeGetComponent.getInputDocument(core, indexedDocId);

        if (null == oldDoc) {
          // log.info("VERSION no doc found, returning true");
          return true;
        }
      }

      if (oldDoc != null) {
        oldUserVersion = oldDoc.getFieldValue(versionFieldName);
        // Make the FieldType resolve any conversion we need.
        oldUserVersion = convertFieldValueUsingType(userVersionField, oldUserVersion);

        Object o = oldDoc.getFieldValue(solrVersionField.getName());
        if (o == null) {
          throw new SolrException(SERVER_ERROR, "No _version_ for document "+ oldDoc);
        }
        oldSolrVersion = o instanceof Number ? ((Number) o).longValue() : Long.parseLong(o.toString());
      }

      // log.info("VERSION old=" + oldUserVersion + " new=" +newUserVersion );

      if ( null == oldUserVersion) {
        // could happen if they turn this feature on after building an index
        // w/o the versionField
        throw new SolrException(SERVER_ERROR,
            "Doc exists in index, but has null versionField: "
                + versionFieldName);
      }

      if (! (oldUserVersion instanceof Comparable && newUserVersion instanceof Comparable) ) {
        throw new SolrException(BAD_REQUEST,
            "old version and new version are not comparable: " +
                oldUserVersion.getClass()+" vs "+newUserVersion.getClass());
      }

      try {
        if (0 < ((Comparable)newUserVersion).compareTo((Comparable) oldUserVersion)) {
          // log.info("VERSION returning true (proceed with update)" );
          return true;
        }
        if (ignoreOldUpdates) {
          if (log.isDebugEnabled()) {
            log.debug("Dropping update since user version is not high enough: " + newUserVersion + "; old user version=" + oldUserVersion);
          }
          // log.info("VERSION returning false (dropping update)" );
          return false;
        } else {
          // log.info("VERSION will throw conflict" );
          throw new SolrException(CONFLICT,
              "user version is not high enough: " + newUserVersion);
        }
      } catch (ClassCastException e) {
        throw new SolrException(BAD_REQUEST,
            "old version and new version are not comparable: " +
                oldUserVersion.getClass()+" vs "+newUserVersion.getClass() +
                ": " + e.getMessage(), e);

      }
    }

    public boolean isLeader(UpdateCommand cmd) {
      if ((cmd.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.PEER_SYNC)) != 0) {
        return false;
      }
      if (phase == DistributedUpdateProcessor.DistribPhase.FROMLEADER) {
        return false;
      }
      // if phase==TOLEADER, we can't just assume we are the leader... let the normal logic check.
      boolean x = distribProc.isLeader(cmd);
      // log.info("VERSION: checking if we are leader:" + x);
      return x;
    }

    public void processAdd(AddUpdateCommand cmd) throws IOException {
      if (!isLeader(cmd)) {
        super.processAdd(cmd);
        return;
      }

      final SolrInputDocument newDoc = cmd.getSolrInputDocument();

      Object newVersion = newDoc.getFieldValue(versionFieldName);
      if ( null == newVersion ) {
        throw new SolrException(BAD_REQUEST, "Doc does not have versionField: " + versionFieldName);
      }

      for (int i=0; ;i++) {
        // Log a warning every 256 retries.... even a few retries should normally be very unusual.
        if ((i&0xff) == 0xff) {
          log.warn("Unusual number of optimistic concurrency retries: retries=" + i + " cmd=" + cmd);
        }

        if (!isVersionNewEnough(cmd.getIndexedId(), newVersion)) {
          // drop older update
          return;
        }

        try {
          cmd.setVersion(oldSolrVersion);  // use optimistic concurrency to ensure that the doc has not changed in the meantime
          super.processAdd(cmd);
          return;
        } catch (SolrException e) {
          if (e.code() == 409) {
            // log.info ("##################### CONFLICT ADDING newDoc=" + newDoc + " newVersion=" + newVersion );
            continue;  // if a version conflict, retry
          }
          throw e;  // rethrow
        }

      }
    }

    public void processDelete(DeleteUpdateCommand cmd) throws IOException {
      if (null == deleteVersionParamName) {
        // not suppose to look at deletes at all
        super.processDelete(cmd);
        return;
      }

      if ( ! cmd.isDeleteById() ) {
        // nothing to do
        super.processDelete(cmd);
        return;
      }

      String deleteParamValue = cmd.getReq().getParams().get(deleteVersionParamName);
      if (null == deleteParamValue) {
        throw new SolrException(BAD_REQUEST,
            "Delete by ID must specify doc version param: " +
                deleteVersionParamName);
      }

      if (!isLeader(cmd)) {
        // transform delete to add earlier rather than later

        SolrInputDocument newDoc = new SolrInputDocument();
        newDoc.setField(core.getLatestSchema().getUniqueKeyField().getName(),
            cmd.getId());
        newDoc.setField(versionFieldName, deleteParamValue);

        AddUpdateCommand newCmd = new AddUpdateCommand(cmd.getReq());
        newCmd.solrDoc = newDoc;
        newCmd.commitWithin = cmd.commitWithin;
        super.processAdd(newCmd);
        return;
      }

      for (int i=0; ;i++) {
        // Log a warning every 256 retries.... even a few retries should normally be very unusual.
        if ((i&0xff) == 0xff) {
          log.warn("Unusual number of optimistic concurrency retries: retries=" + i + " cmd=" + cmd);
        }

        if (!isVersionNewEnough(cmd.getIndexedId(), deleteParamValue)) {
          // drop this older update
          return;
        }

        // :TODO: should this logic be split and driven by two params?
        //   - deleteVersionParam to do a version check
        //   - some new boolean param to determine if a stub document gets added in place?
        try {
          // drop the delete, and instead propogate an AddDoc that
          // replaces the doc with a new "empty" one that records the deleted version

          SolrInputDocument newDoc = new SolrInputDocument();
          newDoc.setField(core.getLatestSchema().getUniqueKeyField().getName(),
              cmd.getId());
          newDoc.setField(versionFieldName, deleteParamValue);

          AddUpdateCommand newCmd = new AddUpdateCommand(cmd.getReq());
          newCmd.solrDoc = newDoc;
          newCmd.commitWithin = cmd.commitWithin;

          newCmd.setVersion(oldSolrVersion);  // use optimistic concurrency to ensure that the doc has not changed in the meantime
          super.processAdd(newCmd);
          return;
        } catch (SolrException e) {
          if (e.code() == 409) {
            continue;  // if a version conflict, retry
          }
          throw e;  // rethrow
        }

      }
    }

  } // end inner class

}


text:
"""
Build a counting Bloom filter from the given sequences, save in <htname>.
Stop collecting reads when the average coverage gets above -C (default 50).
Place reads into -o output_file.

% collect-reads.py <htname> <data1> [ <data2> <...> ]

Use '-h' for parameter help.
"""
from __future__ import division
from __future__ import print_function

import sys
import textwrap
import khmer
from khmer import khmer_args
from khmer.khmer_args import (build_counting_args, report_on_config, info,
                              calculate_graphsize)
from khmer.kfile import check_input_files, check_space
from khmer.kfile import check_space_for_graph
import argparse
import screed

def output_single(read):
    if hasattr(read, 'quality'):
        return "@%s\n%s\n+\n%s\n" % (read.name, read.sequence, read.quality)
    else:
        return ">%s\n%s\n" % (read.name, read.sequence)

def get_parser():
    epilog = """
    The memory usage of this script with :option:`-b` will be about
    1.15x the product of the :option:`-x` and :option:`-N` numbers.

    Example::

        collect-reads.py -k 20 -x 5e7 out.ct data/100k-filtered.fa
    """

    parser = build_counting_args("Collect reads until a given avg coverage.",
                                 epilog=textwrap.dedent(epilog))
    parser.add_argument('output_countgraph_filename', help="The name of the"
                        " file to write the k-mer countgraph to.")
    parser.add_argument('input_sequence_filename', nargs='+',
                        help="The names of one or more FAST[AQ] input "
                        "sequence files.")
    parser.add_argument('--report-total-kmers', '-t', action='store_true',
                        help="Prints the total number of k-mers to stderr")
    parser.add_argument('-C', '--coverage', type=int, default=50,
                        help='Collect reads until this coverage, then exit.')
    parser.add_argument('-o', '--output', type=argparse.FileType('w'),
                        help='Write collect reads into this file.')
    parser.add_argument('-b', '--no-bigcount', dest='bigcount', default=True,
                        action='store_false',
                        help='Do not count k-mers past 255')
    return parser

def main():

    info('collect-reads.py', ['counting'])
    args = get_parser().parse_args()
    report_on_config(args)

    base = args.output_countgraph_filename
    filenames = args.input_sequence_filename

    for name in args.input_sequence_filename:
        check_input_files(name, False)

    check_space(args.input_sequence_filename, False)
    tablesize = calculate_graphsize(args, 'countgraph')
    check_space_for_graph(args.output_countgraph_filename, tablesize,
                              False)

    print('Saving k-mer countgraph to %s' % base)
    print('Loading sequences from %s' % repr(filenames))
    if args.output:
        print('Outputting sequences to', args.output)

    print('making countgraph', file=sys.stderr)
    htable = khmer_args.create_countgraph(args)
    htable.set_use_bigcount(args.bigcount)

    total_coverage = 0.
    n = 0

    for index, filename in enumerate(filenames):
        for record in screed.open(filename):
            seq = record.sequence.upper()
            if 'N' in seq:
                seq = seq.replace('N', 'A')

            try:
                med, _, _ = htable.get_median_count(seq)
            except ValueError:
                continue

            total_coverage += med
            n += 1

            if total_coverage / float(n) > args.coverage:
                print('reached target average coverage:', \
                      total_coverage / float(n))
                break

            htable.consume(seq)
            if args.output:
                args.output.write(output_single(record))

            if n % 100000 == 0:
                print('...', index, filename, n, total_coverage / float(n))

        if total_coverage / float(n) > args.coverage:
            break

    print('Collected %d reads' % (n,))

    if args.report_total_kmers:
        print('Total number of k-mers: {0}'.format(
            htable.n_occupied()), file=sys.stderr)

    print('saving', base)
    htable.save(base)

    info_fp = open(base + '.info', 'w')
    info_fp.write('through end: %s\n' % filenames[-1])

    # Change 0.2 only if you really grok it.  HINT: You don't.
    fp_rate = khmer.calc_expected_collisions(htable, False,
                                             max_false_pos=.2)
    print('fp rate estimated to be %1.3f' % fp_rate)
    print('fp rate estimated to be %1.3f' % fp_rate, file=info_fp)

    print('DONE.')

if __name__ == '__main__':
    main()

# vim: set ft=python ts=4 sts=4 sw=4 et tw=79:


text:
//  ---------------------------------------------
//    Solution:  FileProcessor
//    Project:   FileProcessor
//    File Name: FileProcessor.cs
//
//    Author:    Andrew - 2017/05/30
//  ---------------------------------------------

namespace FileProcessor.Engines
{
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;

    public class FileProcessor<T> : EngineBase<T> where T : class, new()
    {
        protected FileInfo FileInfo { get; set; }

        public FileProcessor(string fileName)
        {
            FileInfo = new FileInfo(fileName);
        }

        protected override TextReader GetReader()
        {
            return FileInfo.OpenText();
        }

        protected override TextWriter GetWriter(bool append)
        {
            return append ? FileInfo.AppendText() : FileInfo.CreateText();
        }

        public List<T> ReadFile()
        {
            return ReadRecords().ToList();
        }

        public void WriteFile(IEnumerable<T> entities, bool append = false)
        {
            WriteRecords(entities, append);
        }
    }
}


text:
/*-------JSHint Directive---------*/
/* global THREE, ThreeGen         */
/*--------------------------------*/
'use strict';

/******************************
 * Entity Animation Functions *
 ******************************/
// ThreeGen.prototype.animateEntity = function(entity) {
//   if (entity.animation.active) {

//     // Key frame animation
//     if (entity.animation.walking) {
//       var time = this.clock.delta % entity.animation.duration;
//       entity.animation.keyframe = Math.floor(time / entity.animation.interpolation) + entity.animation.offset;

//       if (entity.animation.keyframe !== entity.animation.currentKeyFrame) {
//         entity.morphTargetInfluences[entity.animation.lastKeyframe] = 0;
//         entity.morphTargetInfluences[entity.animation.currentKeyframe] = 1;
//         entity.morphTargetInfluences[entity.animation.keyframe] = 0;
//         entity.animation.lastKeyframe = entity.animation.currentKeyframe;
//         entity.animation.currentKeyframe = entity.animation.keyframe;
//       }
//       entity.morphTargetInfluences[entity.animation.keyframe] =
//         (time % entity.animation.interpolation) / entity.animation.interpolation;
//       entity.morphTargetInfluences[entity.animation.lastKeyframe] = 1 -
//         entity.morphTargetInfluences[entity.animation.keyframe];
//     } // End: key frame animation

//   }
// };