").addClass(errClass).css("position", "absolute")
331 | .css("top", el.offsetTop)
332 | .css("left", el.offsetLeft)
333 | // setting width can push out the page size, forcing otherwise
334 | // unnecessary scrollbars to appear and making it impossible for
335 | // the element to shrink; so use max-width instead
336 | .css("maxWidth", el.offsetWidth)
337 | .css("height", el.offsetHeight);
338 | errorDiv.text(err.message);
339 | $el.after(errorDiv);
340 |
341 | // Really dumb way to keep the size/position of the error in sync with
342 | // the parent element as the window is resized or whatever.
343 | var intId = setInterval(function() {
344 | if (!errorDiv[0].parentElement) {
345 | clearInterval(intId);
346 | return;
347 | }
348 | errorDiv
349 | .css("top", el.offsetTop)
350 | .css("left", el.offsetLeft)
351 | .css("maxWidth", el.offsetWidth)
352 | .css("height", el.offsetHeight);
353 | }, 500);
354 | }
355 | }
356 | },
357 | clearError: function(el) {
358 | var $el = $(el);
359 | var display = $el.data("restore-display-mode");
360 | $el.data("restore-display-mode", null);
361 |
362 | if (display === "inline" || display === "inline-block") {
363 | if (display)
364 | $el.css("display", display);
365 | $(el.nextSibling).filter(".htmlwidgets-error").remove();
366 | } else if (display === "block"){
367 | $el.css("visibility", "inherit");
368 | $(el.nextSibling).filter(".htmlwidgets-error").remove();
369 | }
370 | },
371 | sizing: {}
372 | };
373 |
374 | // Called by widget bindings to register a new type of widget. The definition
375 | // object can contain the following properties:
376 | // - name (required) - A string indicating the binding name, which will be
377 | // used by default as the CSS classname to look for.
378 | // - initialize (optional) - A function(el) that will be called once per
379 | // widget element; if a value is returned, it will be passed as the third
380 | // value to renderValue.
381 | // - renderValue (required) - A function(el, data, initValue) that will be
382 | // called with data. Static contexts will cause this to be called once per
383 | // element; Shiny apps will cause this to be called multiple times per
384 | // element, as the data changes.
385 | window.HTMLWidgets.widget = function(definition) {
386 | if (!definition.name) {
387 | throw new Error("Widget must have a name");
388 | }
389 | if (!definition.type) {
390 | throw new Error("Widget must have a type");
391 | }
392 | // Currently we only support output widgets
393 | if (definition.type !== "output") {
394 | throw new Error("Unrecognized widget type '" + definition.type + "'");
395 | }
396 | // TODO: Verify that .name is a valid CSS classname
397 |
398 | // Support new-style instance-bound definitions. Old-style class-bound
399 | // definitions have one widget "object" per widget per type/class of
400 | // widget; the renderValue and resize methods on such widget objects
401 | // take el and instance arguments, because the widget object can't
402 | // store them. New-style instance-bound definitions have one widget
403 | // object per widget instance; the definition that's passed in doesn't
404 | // provide renderValue or resize methods at all, just the single method
405 | // factory(el, width, height)
406 | // which returns an object that has renderValue(x) and resize(w, h).
407 | // This enables a far more natural programming style for the widget
408 | // author, who can store per-instance state using either OO-style
409 | // instance fields or functional-style closure variables (I guess this
410 | // is in contrast to what can only be called C-style pseudo-OO which is
411 | // what we required before).
412 | if (definition.factory) {
413 | definition = createLegacyDefinitionAdapter(definition);
414 | }
415 |
416 | if (!definition.renderValue) {
417 | throw new Error("Widget must have a renderValue function");
418 | }
419 |
420 | // For static rendering (non-Shiny), use a simple widget registration
421 | // scheme. We also use this scheme for Shiny apps/documents that also
422 | // contain static widgets.
423 | window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
424 | // Merge defaults into the definition; don't mutate the original definition.
425 | var staticBinding = extend({}, defaults, definition);
426 | overrideMethod(staticBinding, "find", function(superfunc) {
427 | return function(scope) {
428 | var results = superfunc(scope);
429 | // Filter out Shiny outputs, we only want the static kind
430 | return filterByClass(results, "html-widget-output", false);
431 | };
432 | });
433 | window.HTMLWidgets.widgets.push(staticBinding);
434 |
435 | if (shinyMode) {
436 | // Shiny is running. Register the definition with an output binding.
437 | // The definition itself will not be the output binding, instead
438 | // we will make an output binding object that delegates to the
439 | // definition. This is because we foolishly used the same method
440 | // name (renderValue) for htmlwidgets definition and Shiny bindings
441 | // but they actually have quite different semantics (the Shiny
442 | // bindings receive data that includes lots of metadata that it
443 | // strips off before calling htmlwidgets renderValue). We can't
444 | // just ignore the difference because in some widgets it's helpful
445 | // to call this.renderValue() from inside of resize(), and if
446 | // we're not delegating, then that call will go to the Shiny
447 | // version instead of the htmlwidgets version.
448 |
449 | // Merge defaults with definition, without mutating either.
450 | var bindingDef = extend({}, defaults, definition);
451 |
452 | // This object will be our actual Shiny binding.
453 | var shinyBinding = new Shiny.OutputBinding();
454 |
455 | // With a few exceptions, we'll want to simply use the bindingDef's
456 | // version of methods if they are available, otherwise fall back to
457 | // Shiny's defaults. NOTE: If Shiny's output bindings gain additional
458 | // methods in the future, and we want them to be overrideable by
459 | // HTMLWidget binding definitions, then we'll need to add them to this
460 | // list.
461 | delegateMethod(shinyBinding, bindingDef, "getId");
462 | delegateMethod(shinyBinding, bindingDef, "onValueChange");
463 | delegateMethod(shinyBinding, bindingDef, "onValueError");
464 | delegateMethod(shinyBinding, bindingDef, "renderError");
465 | delegateMethod(shinyBinding, bindingDef, "clearError");
466 | delegateMethod(shinyBinding, bindingDef, "showProgress");
467 |
468 | // The find, renderValue, and resize are handled differently, because we
469 | // want to actually decorate the behavior of the bindingDef methods.
470 |
471 | shinyBinding.find = function(scope) {
472 | var results = bindingDef.find(scope);
473 |
474 | // Only return elements that are Shiny outputs, not static ones
475 | var dynamicResults = results.filter(".html-widget-output");
476 |
477 | // It's possible that whatever caused Shiny to think there might be
478 | // new dynamic outputs, also caused there to be new static outputs.
479 | // Since there might be lots of different htmlwidgets bindings, we
480 | // schedule execution for later--no need to staticRender multiple
481 | // times.
482 | if (results.length !== dynamicResults.length)
483 | scheduleStaticRender();
484 |
485 | return dynamicResults;
486 | };
487 |
488 | // Wrap renderValue to handle initialization, which unfortunately isn't
489 | // supported natively by Shiny at the time of this writing.
490 |
491 | shinyBinding.renderValue = function(el, data) {
492 | Shiny.renderDependencies(data.deps);
493 | // Resolve strings marked as javascript literals to objects
494 | if (!(data.evals instanceof Array)) data.evals = [data.evals];
495 | for (var i = 0; data.evals && i < data.evals.length; i++) {
496 | window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
497 | }
498 | if (!bindingDef.renderOnNullValue) {
499 | if (data.x === null) {
500 | el.style.visibility = "hidden";
501 | return;
502 | } else {
503 | el.style.visibility = "inherit";
504 | }
505 | }
506 | if (!elementData(el, "initialized")) {
507 | initSizing(el);
508 |
509 | elementData(el, "initialized", true);
510 | if (bindingDef.initialize) {
511 | var result = bindingDef.initialize(el, el.offsetWidth,
512 | el.offsetHeight);
513 | elementData(el, "init_result", result);
514 | }
515 | }
516 | bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
517 | evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
518 | };
519 |
520 | // Only override resize if bindingDef implements it
521 | if (bindingDef.resize) {
522 | shinyBinding.resize = function(el, width, height) {
523 | // Shiny can call resize before initialize/renderValue have been
524 | // called, which doesn't make sense for widgets.
525 | if (elementData(el, "initialized")) {
526 | bindingDef.resize(el, width, height, elementData(el, "init_result"));
527 | }
528 | };
529 | }
530 |
531 | Shiny.outputBindings.register(shinyBinding, bindingDef.name);
532 | }
533 | };
534 |
535 | var scheduleStaticRenderTimerId = null;
536 | function scheduleStaticRender() {
537 | if (!scheduleStaticRenderTimerId) {
538 | scheduleStaticRenderTimerId = setTimeout(function() {
539 | scheduleStaticRenderTimerId = null;
540 | window.HTMLWidgets.staticRender();
541 | }, 1);
542 | }
543 | }
544 |
545 | // Render static widgets after the document finishes loading
546 | // Statically render all elements that are of this widget's class
547 | window.HTMLWidgets.staticRender = function() {
548 | var bindings = window.HTMLWidgets.widgets || [];
549 | forEach(bindings, function(binding) {
550 | var matches = binding.find(document.documentElement);
551 | forEach(matches, function(el) {
552 | var sizeObj = initSizing(el, binding);
553 |
554 | if (hasClass(el, "html-widget-static-bound"))
555 | return;
556 | el.className = el.className + " html-widget-static-bound";
557 |
558 | var initResult;
559 | if (binding.initialize) {
560 | initResult = binding.initialize(el,
561 | sizeObj ? sizeObj.getWidth() : el.offsetWidth,
562 | sizeObj ? sizeObj.getHeight() : el.offsetHeight
563 | );
564 | elementData(el, "init_result", initResult);
565 | }
566 |
567 | if (binding.resize) {
568 | var lastSize = {
569 | w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
570 | h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
571 | };
572 | var resizeHandler = function(e) {
573 | var size = {
574 | w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
575 | h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
576 | };
577 | if (size.w === 0 && size.h === 0)
578 | return;
579 | if (size.w === lastSize.w && size.h === lastSize.h)
580 | return;
581 | lastSize = size;
582 | binding.resize(el, size.w, size.h, initResult);
583 | };
584 |
585 | on(window, "resize", resizeHandler);
586 |
587 | // This is needed for cases where we're running in a Shiny
588 | // app, but the widget itself is not a Shiny output, but
589 | // rather a simple static widget. One example of this is
590 | // an rmarkdown document that has runtime:shiny and widget
591 | // that isn't in a render function. Shiny only knows to
592 | // call resize handlers for Shiny outputs, not for static
593 | // widgets, so we do it ourselves.
594 | if (window.jQuery) {
595 | window.jQuery(document).on(
596 | "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
597 | resizeHandler
598 | );
599 | window.jQuery(document).on(
600 | "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
601 | resizeHandler
602 | );
603 | }
604 |
605 | // This is needed for the specific case of ioslides, which
606 | // flips slides between display:none and display:block.
607 | // Ideally we would not have to have ioslide-specific code
608 | // here, but rather have ioslides raise a generic event,
609 | // but the rmarkdown package just went to CRAN so the
610 | // window to getting that fixed may be long.
611 | if (window.addEventListener) {
612 | // It's OK to limit this to window.addEventListener
613 | // browsers because ioslides itself only supports
614 | // such browsers.
615 | on(document, "slideenter", resizeHandler);
616 | on(document, "slideleave", resizeHandler);
617 | }
618 | }
619 |
620 | var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
621 | if (scriptData) {
622 | var data = JSON.parse(scriptData.textContent || scriptData.text);
623 | // Resolve strings marked as javascript literals to objects
624 | if (!(data.evals instanceof Array)) data.evals = [data.evals];
625 | for (var k = 0; data.evals && k < data.evals.length; k++) {
626 | window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
627 | }
628 | binding.renderValue(el, data.x, initResult);
629 | evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
630 | }
631 | });
632 | });
633 |
634 | invokePostRenderHandlers();
635 | }
636 |
637 | // Wait until after the document has loaded to render the widgets.
638 | if (document.addEventListener) {
639 | document.addEventListener("DOMContentLoaded", function() {
640 | document.removeEventListener("DOMContentLoaded", arguments.callee, false);
641 | window.HTMLWidgets.staticRender();
642 | }, false);
643 | } else if (document.attachEvent) {
644 | document.attachEvent("onreadystatechange", function() {
645 | if (document.readyState === "complete") {
646 | document.detachEvent("onreadystatechange", arguments.callee);
647 | window.HTMLWidgets.staticRender();
648 | }
649 | });
650 | }
651 |
652 |
653 | window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
654 | // If no key, default to the first item
655 | if (typeof(key) === "undefined")
656 | key = 1;
657 |
658 | var link = document.getElementById(depname + "-" + key + "-attachment");
659 | if (!link) {
660 | throw new Error("Attachment " + depname + "/" + key + " not found in document");
661 | }
662 | return link.getAttribute("href");
663 | };
664 |
665 | window.HTMLWidgets.dataframeToD3 = function(df) {
666 | var names = [];
667 | var length;
668 | for (var name in df) {
669 | if (df.hasOwnProperty(name))
670 | names.push(name);
671 | if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
672 | throw new Error("All fields must be arrays");
673 | } else if (typeof(length) !== "undefined" && length !== df[name].length) {
674 | throw new Error("All fields must be arrays of the same length");
675 | }
676 | length = df[name].length;
677 | }
678 | var results = [];
679 | var item;
680 | for (var row = 0; row < length; row++) {
681 | item = {};
682 | for (var col = 0; col < names.length; col++) {
683 | item[names[col]] = df[names[col]][row];
684 | }
685 | results.push(item);
686 | }
687 | return results;
688 | };
689 |
690 | window.HTMLWidgets.transposeArray2D = function(array) {
691 | if (array.length === 0) return array;
692 | var newArray = array[0].map(function(col, i) {
693 | return array.map(function(row) {
694 | return row[i]
695 | })
696 | });
697 | return newArray;
698 | };
699 | // Split value at splitChar, but allow splitChar to be escaped
700 | // using escapeChar. Any other characters escaped by escapeChar
701 | // will be included as usual (including escapeChar itself).
702 | function splitWithEscape(value, splitChar, escapeChar) {
703 | var results = [];
704 | var escapeMode = false;
705 | var currentResult = "";
706 | for (var pos = 0; pos < value.length; pos++) {
707 | if (!escapeMode) {
708 | if (value[pos] === splitChar) {
709 | results.push(currentResult);
710 | currentResult = "";
711 | } else if (value[pos] === escapeChar) {
712 | escapeMode = true;
713 | } else {
714 | currentResult += value[pos];
715 | }
716 | } else {
717 | currentResult += value[pos];
718 | escapeMode = false;
719 | }
720 | }
721 | if (currentResult !== "") {
722 | results.push(currentResult);
723 | }
724 | return results;
725 | }
726 | // Function authored by Yihui/JJ Allaire
727 | window.HTMLWidgets.evaluateStringMember = function(o, member) {
728 | var parts = splitWithEscape(member, '.', '\\');
729 | for (var i = 0, l = parts.length; i < l; i++) {
730 | var part = parts[i];
731 | // part may be a character or 'numeric' member name
732 | if (o !== null && typeof o === "object" && part in o) {
733 | if (i == (l - 1)) { // if we are at the end of the line then evalulate
734 | if (typeof o[part] === "string")
735 | o[part] = eval("(" + o[part] + ")");
736 | } else { // otherwise continue to next embedded object
737 | o = o[part];
738 | }
739 | }
740 | }
741 | };
742 |
743 | // Retrieve the HTMLWidget instance (i.e. the return value of an
744 | // HTMLWidget binding's initialize() or factory() function)
745 | // associated with an element, or null if none.
746 | window.HTMLWidgets.getInstance = function(el) {
747 | return elementData(el, "init_result");
748 | };
749 |
750 | // Finds the first element in the scope that matches the selector,
751 | // and returns the HTMLWidget instance (i.e. the return value of
752 | // an HTMLWidget binding's initialize() or factory() function)
753 | // associated with that element, if any. If no element matches the
754 | // selector, or the first matching element has no HTMLWidget
755 | // instance associated with it, then null is returned.
756 | //
757 | // The scope argument is optional, and defaults to window.document.
758 | window.HTMLWidgets.find = function(scope, selector) {
759 | if (arguments.length == 1) {
760 | selector = scope;
761 | scope = document;
762 | }
763 |
764 | var el = scope.querySelector(selector);
765 | if (el === null) {
766 | return null;
767 | } else {
768 | return window.HTMLWidgets.getInstance(el);
769 | }
770 | };
771 |
772 | // Finds all elements in the scope that match the selector, and
773 | // returns the HTMLWidget instances (i.e. the return values of
774 | // an HTMLWidget binding's initialize() or factory() function)
775 | // associated with the elements, in an array. If elements that
776 | // match the selector don't have an associated HTMLWidget
777 | // instance, the returned array will contain nulls.
778 | //
779 | // The scope argument is optional, and defaults to window.document.
780 | window.HTMLWidgets.findAll = function(scope, selector) {
781 | if (arguments.length == 1) {
782 | selector = scope;
783 | scope = document;
784 | }
785 |
786 | var nodes = scope.querySelectorAll(selector);
787 | var results = [];
788 | for (var i = 0; i < nodes.length; i++) {
789 | results.push(window.HTMLWidgets.getInstance(nodes[i]));
790 | }
791 | return results;
792 | };
793 |
794 | var postRenderHandlers = [];
795 | function invokePostRenderHandlers() {
796 | while (postRenderHandlers.length) {
797 | var handler = postRenderHandlers.shift();
798 | if (handler) {
799 | handler();
800 | }
801 | }
802 | }
803 |
804 | // Register the given callback function to be invoked after the
805 | // next time static widgets are rendered.
806 | window.HTMLWidgets.addPostRenderHandler = function(callback) {
807 | postRenderHandlers.push(callback);
808 | };
809 |
810 | // Takes a new-style instance-bound definition, and returns an
811 | // old-style class-bound definition. This saves us from having
812 | // to rewrite all the logic in this file to accomodate both
813 | // types of definitions.
814 | function createLegacyDefinitionAdapter(defn) {
815 | var result = {
816 | name: defn.name,
817 | type: defn.type,
818 | initialize: function(el, width, height) {
819 | return defn.factory(el, width, height);
820 | },
821 | renderValue: function(el, x, instance) {
822 | return instance.renderValue(x);
823 | },
824 | resize: function(el, width, height, instance) {
825 | return instance.resize(width, height);
826 | }
827 | };
828 |
829 | if (defn.find)
830 | result.find = defn.find;
831 | if (defn.renderError)
832 | result.renderError = defn.renderError;
833 | if (defn.clearError)
834 | result.clearError = defn.clearError;
835 |
836 | return result;
837 | }
838 | })();
839 |
840 |
--------------------------------------------------------------------------------
/libs/jquery/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2005, 2014 jQuery Foundation and other contributors,
2 | https://jquery.org/
3 |
4 | This software consists of voluntary contributions made by many
5 | individuals. For exact contribution history, see the revision history
6 | available at https://github.com/jquery/jquery
7 |
8 | The following license applies to all parts of this software except as
9 | documented below:
10 |
11 | ====
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining
14 | a copy of this software and associated documentation files (the
15 | "Software"), to deal in the Software without restriction, including
16 | without limitation the rights to use, copy, modify, merge, publish,
17 | distribute, sublicense, and/or sell copies of the Software, and to
18 | permit persons to whom the Software is furnished to do so, subject to
19 | the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be
22 | included in all copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 |
32 | ====
33 |
34 | All files located in the node_modules and external directories are
35 | externally maintained libraries used by this software which have their
36 | own licenses; we recommend you read them, as their terms may differ from
37 | the terms above.
38 |
--------------------------------------------------------------------------------
/libs/leaflet/images/layers-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/layers-2x.png
--------------------------------------------------------------------------------
/libs/leaflet/images/layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/layers.png
--------------------------------------------------------------------------------
/libs/leaflet/images/marker-icon-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/marker-icon-2x.png
--------------------------------------------------------------------------------
/libs/leaflet/images/marker-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/marker-icon.png
--------------------------------------------------------------------------------
/libs/leaflet/images/marker-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/marker-shadow.png
--------------------------------------------------------------------------------
/libs/leaflet/leaflet.css:
--------------------------------------------------------------------------------
1 | /* required styles */
2 |
3 | .leaflet-pane,
4 | .leaflet-tile,
5 | .leaflet-marker-icon,
6 | .leaflet-marker-shadow,
7 | .leaflet-tile-container,
8 | .leaflet-pane > svg,
9 | .leaflet-pane > canvas,
10 | .leaflet-zoom-box,
11 | .leaflet-image-layer,
12 | .leaflet-layer {
13 | position: absolute;
14 | left: 0;
15 | top: 0;
16 | }
17 | .leaflet-container {
18 | overflow: hidden;
19 | }
20 | .leaflet-tile,
21 | .leaflet-marker-icon,
22 | .leaflet-marker-shadow {
23 | -webkit-user-select: none;
24 | -moz-user-select: none;
25 | user-select: none;
26 | -webkit-user-drag: none;
27 | }
28 | /* Safari renders non-retina tile on retina better with this, but Chrome is worse */
29 | .leaflet-safari .leaflet-tile {
30 | image-rendering: -webkit-optimize-contrast;
31 | }
32 | /* hack that prevents hw layers "stretching" when loading new tiles */
33 | .leaflet-safari .leaflet-tile-container {
34 | width: 1600px;
35 | height: 1600px;
36 | -webkit-transform-origin: 0 0;
37 | }
38 | .leaflet-marker-icon,
39 | .leaflet-marker-shadow {
40 | display: block;
41 | }
42 | /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
43 | /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
44 | .leaflet-container .leaflet-overlay-pane svg,
45 | .leaflet-container .leaflet-marker-pane img,
46 | .leaflet-container .leaflet-shadow-pane img,
47 | .leaflet-container .leaflet-tile-pane img,
48 | .leaflet-container img.leaflet-image-layer {
49 | max-width: none !important;
50 | max-height: none !important;
51 | }
52 |
53 | .leaflet-container.leaflet-touch-zoom {
54 | -ms-touch-action: pan-x pan-y;
55 | touch-action: pan-x pan-y;
56 | }
57 | .leaflet-container.leaflet-touch-drag {
58 | -ms-touch-action: pinch-zoom;
59 | /* Fallback for FF which doesn't support pinch-zoom */
60 | touch-action: none;
61 | touch-action: pinch-zoom;
62 | }
63 | .leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
64 | -ms-touch-action: none;
65 | touch-action: none;
66 | }
67 | .leaflet-container {
68 | -webkit-tap-highlight-color: transparent;
69 | }
70 | .leaflet-container a {
71 | -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
72 | }
73 | .leaflet-tile {
74 | filter: inherit;
75 | visibility: hidden;
76 | }
77 | .leaflet-tile-loaded {
78 | visibility: inherit;
79 | }
80 | .leaflet-zoom-box {
81 | width: 0;
82 | height: 0;
83 | -moz-box-sizing: border-box;
84 | box-sizing: border-box;
85 | z-index: 800;
86 | }
87 | /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
88 | .leaflet-overlay-pane svg {
89 | -moz-user-select: none;
90 | }
91 |
92 | .leaflet-pane { z-index: 400; }
93 |
94 | .leaflet-tile-pane { z-index: 200; }
95 | .leaflet-overlay-pane { z-index: 400; }
96 | .leaflet-shadow-pane { z-index: 500; }
97 | .leaflet-marker-pane { z-index: 600; }
98 | .leaflet-tooltip-pane { z-index: 650; }
99 | .leaflet-popup-pane { z-index: 700; }
100 |
101 | .leaflet-map-pane canvas { z-index: 100; }
102 | .leaflet-map-pane svg { z-index: 200; }
103 |
104 | .leaflet-vml-shape {
105 | width: 1px;
106 | height: 1px;
107 | }
108 | .lvml {
109 | behavior: url(#default#VML);
110 | display: inline-block;
111 | position: absolute;
112 | }
113 |
114 |
115 | /* control positioning */
116 |
117 | .leaflet-control {
118 | position: relative;
119 | z-index: 800;
120 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
121 | pointer-events: auto;
122 | }
123 | .leaflet-top,
124 | .leaflet-bottom {
125 | position: absolute;
126 | z-index: 1000;
127 | pointer-events: none;
128 | }
129 | .leaflet-top {
130 | top: 0;
131 | }
132 | .leaflet-right {
133 | right: 0;
134 | }
135 | .leaflet-bottom {
136 | bottom: 0;
137 | }
138 | .leaflet-left {
139 | left: 0;
140 | }
141 | .leaflet-control {
142 | float: left;
143 | clear: both;
144 | }
145 | .leaflet-right .leaflet-control {
146 | float: right;
147 | }
148 | .leaflet-top .leaflet-control {
149 | margin-top: 10px;
150 | }
151 | .leaflet-bottom .leaflet-control {
152 | margin-bottom: 10px;
153 | }
154 | .leaflet-left .leaflet-control {
155 | margin-left: 10px;
156 | }
157 | .leaflet-right .leaflet-control {
158 | margin-right: 10px;
159 | }
160 |
161 |
162 | /* zoom and fade animations */
163 |
164 | .leaflet-fade-anim .leaflet-tile {
165 | will-change: opacity;
166 | }
167 | .leaflet-fade-anim .leaflet-popup {
168 | opacity: 0;
169 | -webkit-transition: opacity 0.2s linear;
170 | -moz-transition: opacity 0.2s linear;
171 | -o-transition: opacity 0.2s linear;
172 | transition: opacity 0.2s linear;
173 | }
174 | .leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
175 | opacity: 1;
176 | }
177 | .leaflet-zoom-animated {
178 | -webkit-transform-origin: 0 0;
179 | -ms-transform-origin: 0 0;
180 | transform-origin: 0 0;
181 | }
182 | .leaflet-zoom-anim .leaflet-zoom-animated {
183 | will-change: transform;
184 | }
185 | .leaflet-zoom-anim .leaflet-zoom-animated {
186 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
187 | -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
188 | -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
189 | transition: transform 0.25s cubic-bezier(0,0,0.25,1);
190 | }
191 | .leaflet-zoom-anim .leaflet-tile,
192 | .leaflet-pan-anim .leaflet-tile {
193 | -webkit-transition: none;
194 | -moz-transition: none;
195 | -o-transition: none;
196 | transition: none;
197 | }
198 |
199 | .leaflet-zoom-anim .leaflet-zoom-hide {
200 | visibility: hidden;
201 | }
202 |
203 |
204 | /* cursors */
205 |
206 | .leaflet-interactive {
207 | cursor: pointer;
208 | }
209 | .leaflet-grab {
210 | cursor: -webkit-grab;
211 | cursor: -moz-grab;
212 | }
213 | .leaflet-crosshair,
214 | .leaflet-crosshair .leaflet-interactive {
215 | cursor: crosshair;
216 | }
217 | .leaflet-popup-pane,
218 | .leaflet-control {
219 | cursor: auto;
220 | }
221 | .leaflet-dragging .leaflet-grab,
222 | .leaflet-dragging .leaflet-grab .leaflet-interactive,
223 | .leaflet-dragging .leaflet-marker-draggable {
224 | cursor: move;
225 | cursor: -webkit-grabbing;
226 | cursor: -moz-grabbing;
227 | }
228 |
229 | /* marker & overlays interactivity */
230 | .leaflet-marker-icon,
231 | .leaflet-marker-shadow,
232 | .leaflet-image-layer,
233 | .leaflet-pane > svg path,
234 | .leaflet-tile-container {
235 | pointer-events: none;
236 | }
237 |
238 | .leaflet-marker-icon.leaflet-interactive,
239 | .leaflet-image-layer.leaflet-interactive,
240 | .leaflet-pane > svg path.leaflet-interactive {
241 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
242 | pointer-events: auto;
243 | }
244 |
245 | /* visual tweaks */
246 |
247 | .leaflet-container {
248 | background: #ddd;
249 | outline: 0;
250 | }
251 | .leaflet-container a {
252 | color: #0078A8;
253 | }
254 | .leaflet-container a.leaflet-active {
255 | outline: 2px solid orange;
256 | }
257 | .leaflet-zoom-box {
258 | border: 2px dotted #38f;
259 | background: rgba(255,255,255,0.5);
260 | }
261 |
262 |
263 | /* general typography */
264 | .leaflet-container {
265 | font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
266 | }
267 |
268 |
269 | /* general toolbar styles */
270 |
271 | .leaflet-bar {
272 | box-shadow: 0 1px 5px rgba(0,0,0,0.65);
273 | border-radius: 4px;
274 | }
275 | .leaflet-bar a,
276 | .leaflet-bar a:hover {
277 | background-color: #fff;
278 | border-bottom: 1px solid #ccc;
279 | width: 26px;
280 | height: 26px;
281 | line-height: 26px;
282 | display: block;
283 | text-align: center;
284 | text-decoration: none;
285 | color: black;
286 | }
287 | .leaflet-bar a,
288 | .leaflet-control-layers-toggle {
289 | background-position: 50% 50%;
290 | background-repeat: no-repeat;
291 | display: block;
292 | }
293 | .leaflet-bar a:hover {
294 | background-color: #f4f4f4;
295 | }
296 | .leaflet-bar a:first-child {
297 | border-top-left-radius: 4px;
298 | border-top-right-radius: 4px;
299 | }
300 | .leaflet-bar a:last-child {
301 | border-bottom-left-radius: 4px;
302 | border-bottom-right-radius: 4px;
303 | border-bottom: none;
304 | }
305 | .leaflet-bar a.leaflet-disabled {
306 | cursor: default;
307 | background-color: #f4f4f4;
308 | color: #bbb;
309 | }
310 |
311 | .leaflet-touch .leaflet-bar a {
312 | width: 30px;
313 | height: 30px;
314 | line-height: 30px;
315 | }
316 | .leaflet-touch .leaflet-bar a:first-child {
317 | border-top-left-radius: 2px;
318 | border-top-right-radius: 2px;
319 | }
320 | .leaflet-touch .leaflet-bar a:last-child {
321 | border-bottom-left-radius: 2px;
322 | border-bottom-right-radius: 2px;
323 | }
324 |
325 | /* zoom control */
326 |
327 | .leaflet-control-zoom-in,
328 | .leaflet-control-zoom-out {
329 | font: bold 18px 'Lucida Console', Monaco, monospace;
330 | text-indent: 1px;
331 | }
332 |
333 | .leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
334 | font-size: 22px;
335 | }
336 |
337 |
338 | /* layers control */
339 |
340 | .leaflet-control-layers {
341 | box-shadow: 0 1px 5px rgba(0,0,0,0.4);
342 | background: #fff;
343 | border-radius: 5px;
344 | }
345 | .leaflet-control-layers-toggle {
346 | background-image: url(images/layers.png);
347 | width: 36px;
348 | height: 36px;
349 | }
350 | .leaflet-retina .leaflet-control-layers-toggle {
351 | background-image: url(images/layers-2x.png);
352 | background-size: 26px 26px;
353 | }
354 | .leaflet-touch .leaflet-control-layers-toggle {
355 | width: 44px;
356 | height: 44px;
357 | }
358 | .leaflet-control-layers .leaflet-control-layers-list,
359 | .leaflet-control-layers-expanded .leaflet-control-layers-toggle {
360 | display: none;
361 | }
362 | .leaflet-control-layers-expanded .leaflet-control-layers-list {
363 | display: block;
364 | position: relative;
365 | }
366 | .leaflet-control-layers-expanded {
367 | padding: 6px 10px 6px 6px;
368 | color: #333;
369 | background: #fff;
370 | }
371 | .leaflet-control-layers-scrollbar {
372 | overflow-y: scroll;
373 | overflow-x: hidden;
374 | padding-right: 5px;
375 | }
376 | .leaflet-control-layers-selector {
377 | margin-top: 2px;
378 | position: relative;
379 | top: 1px;
380 | }
381 | .leaflet-control-layers label {
382 | display: block;
383 | }
384 | .leaflet-control-layers-separator {
385 | height: 0;
386 | border-top: 1px solid #ddd;
387 | margin: 5px -10px 5px -6px;
388 | }
389 |
390 | /* Default icon URLs */
391 | .leaflet-default-icon-path {
392 | background-image: url(images/marker-icon.png);
393 | }
394 |
395 |
396 | /* attribution and scale controls */
397 |
398 | .leaflet-container .leaflet-control-attribution {
399 | background: #fff;
400 | background: rgba(255, 255, 255, 0.7);
401 | margin: 0;
402 | }
403 | .leaflet-control-attribution,
404 | .leaflet-control-scale-line {
405 | padding: 0 5px;
406 | color: #333;
407 | }
408 | .leaflet-control-attribution a {
409 | text-decoration: none;
410 | }
411 | .leaflet-control-attribution a:hover {
412 | text-decoration: underline;
413 | }
414 | .leaflet-container .leaflet-control-attribution,
415 | .leaflet-container .leaflet-control-scale {
416 | font-size: 11px;
417 | }
418 | .leaflet-left .leaflet-control-scale {
419 | margin-left: 5px;
420 | }
421 | .leaflet-bottom .leaflet-control-scale {
422 | margin-bottom: 5px;
423 | }
424 | .leaflet-control-scale-line {
425 | border: 2px solid #777;
426 | border-top: none;
427 | line-height: 1.1;
428 | padding: 2px 5px 1px;
429 | font-size: 11px;
430 | white-space: nowrap;
431 | overflow: hidden;
432 | -moz-box-sizing: border-box;
433 | box-sizing: border-box;
434 |
435 | background: #fff;
436 | background: rgba(255, 255, 255, 0.5);
437 | }
438 | .leaflet-control-scale-line:not(:first-child) {
439 | border-top: 2px solid #777;
440 | border-bottom: none;
441 | margin-top: -2px;
442 | }
443 | .leaflet-control-scale-line:not(:first-child):not(:last-child) {
444 | border-bottom: 2px solid #777;
445 | }
446 |
447 | .leaflet-touch .leaflet-control-attribution,
448 | .leaflet-touch .leaflet-control-layers,
449 | .leaflet-touch .leaflet-bar {
450 | box-shadow: none;
451 | }
452 | .leaflet-touch .leaflet-control-layers,
453 | .leaflet-touch .leaflet-bar {
454 | border: 2px solid rgba(0,0,0,0.2);
455 | background-clip: padding-box;
456 | }
457 |
458 |
459 | /* popup */
460 |
461 | .leaflet-popup {
462 | position: absolute;
463 | text-align: center;
464 | margin-bottom: 20px;
465 | }
466 | .leaflet-popup-content-wrapper {
467 | padding: 1px;
468 | text-align: left;
469 | border-radius: 12px;
470 | }
471 | .leaflet-popup-content {
472 | margin: 13px 19px;
473 | line-height: 1.4;
474 | }
475 | .leaflet-popup-content p {
476 | margin: 18px 0;
477 | }
478 | .leaflet-popup-tip-container {
479 | width: 40px;
480 | height: 20px;
481 | position: absolute;
482 | left: 50%;
483 | margin-left: -20px;
484 | overflow: hidden;
485 | pointer-events: none;
486 | }
487 | .leaflet-popup-tip {
488 | width: 17px;
489 | height: 17px;
490 | padding: 1px;
491 |
492 | margin: -10px auto 0;
493 |
494 | -webkit-transform: rotate(45deg);
495 | -moz-transform: rotate(45deg);
496 | -ms-transform: rotate(45deg);
497 | -o-transform: rotate(45deg);
498 | transform: rotate(45deg);
499 | }
500 | .leaflet-popup-content-wrapper,
501 | .leaflet-popup-tip {
502 | background: white;
503 | color: #333;
504 | box-shadow: 0 3px 14px rgba(0,0,0,0.4);
505 | }
506 | .leaflet-container a.leaflet-popup-close-button {
507 | position: absolute;
508 | top: 0;
509 | right: 0;
510 | padding: 4px 4px 0 0;
511 | border: none;
512 | text-align: center;
513 | width: 18px;
514 | height: 14px;
515 | font: 16px/14px Tahoma, Verdana, sans-serif;
516 | color: #c3c3c3;
517 | text-decoration: none;
518 | font-weight: bold;
519 | background: transparent;
520 | }
521 | .leaflet-container a.leaflet-popup-close-button:hover {
522 | color: #999;
523 | }
524 | .leaflet-popup-scrolled {
525 | overflow: auto;
526 | border-bottom: 1px solid #ddd;
527 | border-top: 1px solid #ddd;
528 | }
529 |
530 | .leaflet-oldie .leaflet-popup-content-wrapper {
531 | zoom: 1;
532 | }
533 | .leaflet-oldie .leaflet-popup-tip {
534 | width: 24px;
535 | margin: 0 auto;
536 |
537 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
538 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
539 | }
540 | .leaflet-oldie .leaflet-popup-tip-container {
541 | margin-top: -1px;
542 | }
543 |
544 | .leaflet-oldie .leaflet-control-zoom,
545 | .leaflet-oldie .leaflet-control-layers,
546 | .leaflet-oldie .leaflet-popup-content-wrapper,
547 | .leaflet-oldie .leaflet-popup-tip {
548 | border: 1px solid #999;
549 | }
550 |
551 |
552 | /* div icon */
553 |
554 | .leaflet-div-icon {
555 | background: #fff;
556 | border: 1px solid #666;
557 | }
558 |
559 |
560 | /* Tooltip */
561 | /* Base styles for the element that has a tooltip */
562 | .leaflet-tooltip {
563 | position: absolute;
564 | padding: 6px;
565 | background-color: #fff;
566 | border: 1px solid #fff;
567 | border-radius: 3px;
568 | color: #222;
569 | white-space: nowrap;
570 | -webkit-user-select: none;
571 | -moz-user-select: none;
572 | -ms-user-select: none;
573 | user-select: none;
574 | pointer-events: none;
575 | box-shadow: 0 1px 3px rgba(0,0,0,0.4);
576 | }
577 | .leaflet-tooltip.leaflet-clickable {
578 | cursor: pointer;
579 | pointer-events: auto;
580 | }
581 | .leaflet-tooltip-top:before,
582 | .leaflet-tooltip-bottom:before,
583 | .leaflet-tooltip-left:before,
584 | .leaflet-tooltip-right:before {
585 | position: absolute;
586 | pointer-events: none;
587 | border: 6px solid transparent;
588 | background: transparent;
589 | content: "";
590 | }
591 |
592 | /* Directions */
593 |
594 | .leaflet-tooltip-bottom {
595 | margin-top: 6px;
596 | }
597 | .leaflet-tooltip-top {
598 | margin-top: -6px;
599 | }
600 | .leaflet-tooltip-bottom:before,
601 | .leaflet-tooltip-top:before {
602 | left: 50%;
603 | margin-left: -6px;
604 | }
605 | .leaflet-tooltip-top:before {
606 | bottom: 0;
607 | margin-bottom: -12px;
608 | border-top-color: #fff;
609 | }
610 | .leaflet-tooltip-bottom:before {
611 | top: 0;
612 | margin-top: -12px;
613 | margin-left: -6px;
614 | border-bottom-color: #fff;
615 | }
616 | .leaflet-tooltip-left {
617 | margin-left: -6px;
618 | }
619 | .leaflet-tooltip-right {
620 | margin-left: 6px;
621 | }
622 | .leaflet-tooltip-left:before,
623 | .leaflet-tooltip-right:before {
624 | top: 50%;
625 | margin-top: -6px;
626 | }
627 | .leaflet-tooltip-left:before {
628 | right: 0;
629 | margin-right: -12px;
630 | border-left-color: #fff;
631 | }
632 | .leaflet-tooltip-right:before {
633 | left: 0;
634 | margin-left: -12px;
635 | border-right-color: #fff;
636 | }
637 |
--------------------------------------------------------------------------------
/libs/leafletfix/leafletfix.css:
--------------------------------------------------------------------------------
1 | /* Work around CSS properties introduced on img by bootstrap */
2 | img.leaflet-tile {
3 | padding: 0;
4 | margin: 0;
5 | border-radius: 0;
6 | border: none;
7 | }
8 | .info {
9 | padding: 6px 8px;
10 | font: 14px/16px Arial, Helvetica, sans-serif;
11 | background: white;
12 | background: rgba(255,255,255,0.8);
13 | box-shadow: 0 0 15px rgba(0,0,0,0.2);
14 | border-radius: 5px;
15 | }
16 | .legend {
17 | line-height: 18px;
18 | color: #555;
19 | }
20 | .legend svg text {
21 | fill: #555;
22 | }
23 | .legend svg line {
24 | stroke: #555;
25 | }
26 | .legend i {
27 | width: 18px;
28 | height: 18px;
29 | margin-right: 4px;
30 | opacity: 0.7;
31 | display: inline-block;
32 | vertical-align: top;
33 | /*For IE 7*/
34 | zoom: 1;
35 | *display: inline;
36 | }
37 |
--------------------------------------------------------------------------------
/libs/remark-css/default.css:
--------------------------------------------------------------------------------
1 | a, a > code {
2 | color: rgb(249, 38, 114);
3 | text-decoration: none;
4 | }
5 | .footnote {
6 | position: absolute;
7 | bottom: 3em;
8 | padding-right: 4em;
9 | font-size: 90%;
10 | }
11 | .remark-code-line-highlighted { background-color: #ffff88; }
12 |
13 | .inverse {
14 | background-color: #272822;
15 | color: #d6d6d6;
16 | text-shadow: 0 0 20px #333;
17 | }
18 | .inverse h1, .inverse h2, .inverse h3 {
19 | color: #f3f3f3;
20 | }
21 | /* Two-column layout */
22 | .left-column {
23 | color: #777;
24 | width: 20%;
25 | height: 92%;
26 | float: left;
27 | }
28 | .left-column h2:last-of-type, .left-column h3:last-child {
29 | color: #000;
30 | }
31 | .right-column {
32 | width: 75%;
33 | float: right;
34 | padding-top: 1em;
35 | }
36 | .pull-left {
37 | float: left;
38 | width: 47%;
39 | }
40 | .pull-right {
41 | float: right;
42 | width: 47%;
43 | }
44 | .pull-right ~ * {
45 | clear: both;
46 | }
47 | img, video, iframe {
48 | max-width: 100%;
49 | }
50 | blockquote {
51 | border-left: solid 5px lightgray;
52 | padding-left: 1em;
53 | }
54 | .remark-slide table {
55 | margin: auto;
56 | border-top: 1px solid #666;
57 | border-bottom: 1px solid #666;
58 | }
59 | .remark-slide table thead th { border-bottom: 1px solid #ddd; }
60 | th, td { padding: 5px; }
61 | .remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee }
62 |
63 | @page { margin: 0; }
64 | @media print {
65 | .remark-slide-scaler {
66 | width: 100% !important;
67 | height: 100% !important;
68 | transform: scale(1) !important;
69 | top: 0 !important;
70 | left: 0 !important;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/libs/remark-css/lucy-fonts.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Lato);
2 | @import url(https://fonts.googleapis.com/css?family=Anton);
3 | @import url('https://fonts.googleapis.com/css?family=Inconsolata:400,700');
4 |
5 | body, h2, h3 {
6 | font-family: 'Lato', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif;
7 | }
8 |
9 | h1 {
10 | font-family: 'Anton';
11 | }
12 |
13 | .remark-code, .remark-inline-code {
14 | font-family: 'Inconsolata', 'Lucida Console', Monaco, monospace;
15 | }
16 |
--------------------------------------------------------------------------------
/libs/remark-css/rladies.css:
--------------------------------------------------------------------------------
1 | h1, h2, h3 {
2 | font-weight: normal;
3 | color: #562457;
4 | }
5 | a, a > code {
6 | color: #88398a;
7 | }
8 | .remark-code-line-highlighted { background-color: rgba(136, 57, 138, 0.3); }
9 |
10 | .inverse {
11 | background-color: #562457;
12 | }
13 | .inverse, .inverse h1, .inverse h2, .inverse h3, .inverse a, inverse a > code {
14 | color: #fff;
15 | }
16 |
--------------------------------------------------------------------------------
/libs/rstudio_leaflet/images/1px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/rstudio_leaflet/images/1px.png
--------------------------------------------------------------------------------
/libs/rstudio_leaflet/rstudio_leaflet.css:
--------------------------------------------------------------------------------
1 | .leaflet-tooltip.leaflet-tooltip-text-only,
2 | .leaflet-tooltip.leaflet-tooltip-text-only:before,
3 | .leaflet-tooltip.leaflet-tooltip-text-only:after {
4 | background: none;
5 | border: none;
6 | box-shadow: none;
7 | }
8 |
9 | .leaflet-tooltip.leaflet-tooltip-text-only.leaflet-tooltip-left {
10 | margin-left: 5px;
11 | }
12 |
13 | .leaflet-tooltip.leaflet-tooltip-text-only.leaflet-tooltip-right {
14 | margin-left: -5px;
15 | }
16 |
17 | .leaflet-tooltip:after {
18 | border-right: 6px solid transparent;
19 | /* right: -16px; */
20 | }
21 |
22 | .leaflet-popup-pane .leaflet-popup-tip-container {
23 | /* when the tooltip container is clicked, it is closed */
24 | pointer-events: all;
25 | /* tooltips should display the "hand" icon, just like .leaflet-interactive*/
26 | cursor: pointer;
27 | }
28 |
29 | /* have the widget be displayed in the right 'layer' */
30 | .leaflet-map-pane {
31 | z-index: auto;
32 | }
33 |
--------------------------------------------------------------------------------
/my-style.css:
--------------------------------------------------------------------------------
1 | .red { color: red; }
2 | .remark-code-line-highlighted { background-color: #e8c9e9; }
3 | .remark-code, .remark-inline-code {
4 | color: #7c347f;
5 | font-weight: 300;
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/templates/xaringan-themer.css:
--------------------------------------------------------------------------------
1 | /* -------------------------------------------------------
2 | *
3 | * !! This file was generated by xaringanthemer !!
4 | *
5 | * Changes made to this file directly will be overwritten
6 | * if you used xaringanthemer in your xaringan slides Rmd
7 | *
8 | * Issues or likes?
9 | * - https://github.com/gadenbuie/xaringanthemer
10 | * - https://www.garrickadenbuie.com
11 | *
12 | * Need help? Try:
13 | * - vignette(package = "xaringanthemer")
14 | * - ?xaringanthemer::write_xaringan_theme
15 | * - xaringan wiki: https://github.com/yihui/xaringan/wiki
16 | * - remarkjs wiki: https://github.com/gnab/remark/wiki
17 | *
18 | * ------------------------------------------------------- */
19 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
20 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
21 | @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700);
22 |
23 |
24 | body {
25 | font-family: 'Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif;
26 | font-weight: normal;
27 | color: #000;
28 | }
29 | h1, h2, h3 {
30 | font-family: 'Yanone Kaffeesatz';
31 | font-weight: normal;
32 | color: #FFFFF;
33 | }
34 | .remark-slide-content {
35 | background-color: #FFF;
36 | font-size: 20px;
37 |
38 |
39 |
40 | padding: 1em 4em 1em 4em;
41 | }
42 | .remark-slide-content h1 {
43 | font-size: 55px;
44 | }
45 | .remark-slide-content h2 {
46 | font-size: 45px;
47 | }
48 | .remark-slide-content h3 {
49 | font-size: 35px;
50 | }
51 | .remark-code, .remark-inline-code {
52 | font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace;
53 | }
54 | .remark-code {
55 | font-size: 0.9em;
56 | }
57 | .remark-inline-code {
58 | font-size: 1em;
59 | color: #000;
60 |
61 |
62 | }
63 | .remark-slide-number {
64 | color: #272822;
65 | opacity: 1;
66 | font-size: 0.9em;
67 | }
68 |
69 | a, a > code {
70 | color: rgb(249, 38, 114);
71 | text-decoration: none;
72 | }
73 | .footnote {
74 |
75 | position: absolute;
76 | bottom: 3em;
77 | padding-right: 4em;
78 | font-size: 0.9em;
79 | }
80 | .remark-code-line-highlighted {
81 | background-color: rgba(255,255,0,0.5);
82 | }
83 | .inverse {
84 | background-color: #272822;
85 | color: #d6d6d6;
86 |
87 | }
88 | .inverse h1, .inverse h2, .inverse h3 {
89 | color: #f3f3f3;
90 | }
91 | .title-slide, .title-slide h1, .title-slide h2, .title-slide h3 {
92 | color: #d6d6d6;
93 | }
94 | .title-slide {
95 | background-color: #272822;
96 |
97 |
98 |
99 | }
100 | .title-slide .remark-slide-number {
101 | display: none;
102 | }
103 | /* Two-column layout */
104 | .left-column {
105 | width: 20%;
106 | height: 92%;
107 | float: left;
108 | }
109 | .left-column h2, .left-column h3 {
110 | color: #777;
111 | }
112 | .left-column h2:last-of-type, .left-column h3:last-child {
113 | color: #000;
114 | }
115 | .right-column {
116 | width: 75%;
117 | float: right;
118 | padding-top: 1em;
119 | }
120 | .pull-left {
121 | float: left;
122 | width: 47%;
123 | }
124 | .pull-right {
125 | float: right;
126 | width: 47%;
127 | }
128 | .pull-right ~ * {
129 | clear: both;
130 | }
131 | img, video, iframe {
132 | max-width: 100%;
133 | }
134 | blockquote {
135 | border-left: solid 5px lightgray;
136 | padding-left: 1em;
137 | }
138 | .remark-slide table {
139 | margin: auto;
140 | border-top: 1px solid #666;
141 | border-bottom: 1px solid #666;
142 | }
143 | .remark-slide table thead th { border-bottom: 1px solid #ddd; }
144 | th, td { padding: 5px; }
145 | .remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee }
146 | table.dataTable tbody {
147 | background-color: #FFF;
148 | color: #000;
149 | }
150 | table.dataTable.display tbody tr.odd {
151 | background-color: #FFF;
152 | }
153 | table.dataTable.display tbody tr.even {
154 | background-color: #eee;
155 | }
156 | table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
157 | background-color: rgba(255, 255, 255, 0.5);
158 | }
159 | .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate {
160 | color: #000;
161 | }
162 | .dataTables_wrapper .dataTables_paginate .paginate_button {
163 | color: #000 !important;
164 | }
165 |
166 | @page { margin: 0; }
167 | @media print {
168 | .remark-slide-scaler {
169 | width: 100% !important;
170 | height: 100% !important;
171 | transform: scale(1) !important;
172 | top: 0 !important;
173 | left: 0 !important;
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/templates/xaringanthemer.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "
OCRUG Themed Presentation \u6A59"
3 | subtitle: "with xaringan and xaringanthemer"
4 | author: "Zhi Yang"
5 | date: '`r Sys.Date()`'
6 | output:
7 | xaringan::moon_reader:
8 | lib_dir: libs
9 | css: xaringan-themer.css
10 | nature:
11 | highlightStyle: github
12 | highlightLines: true
13 | countIncrementalSlides: false
14 | ---
15 |
16 | ```{r setup, include=FALSE}
17 | options(htmltools.dir.version = FALSE)
18 | ```
19 |
20 | ```{r xaringan-themer, include=FALSE, eval=TRUE}
21 | library(xaringanthemer)
22 | mono_accent(
23 | base_color = "#f38313",
24 | code_highlight_color = "#fce6cf"
25 | )
26 | ```
27 |
28 |
29 | # Hello World
30 |
31 | Install the **xaringan** package from [Github](https://github.com/yihui/xaringan):
32 |
33 | ```{r eval=FALSE, tidy=FALSE}
34 | devtools::install_github("yihui/xaringan") #<<
35 | plot(cars)
36 | ```
37 |
38 |
39 | You are recommended to use the [RStudio IDE](https://www.rstudio.com/products/rstudio/), but you do not have to.
40 |
41 | - Create a new R Markdown document from the menu `File -> New File -> R Markdown -> From Template -> Ninja Presentation`;
1
42 |
43 |
44 | - Click the `Knit` button to compile it;
45 |
46 |
47 | - or use the [RStudio Addin](https://rstudio.github.io/rstudioaddins/)
2 "Infinite Moon Reader" to live preview the slides (every time you update and save the Rmd document, the slides will be automatically reloaded in RStudio Viewer.
48 |
49 |
--------------------------------------------------------------------------------
/templates/xaringanthemer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
OCRUG Themed Presentation 橙
5 |
6 |
7 |
8 |
9 |
10 |
11 |
48 |
49 |
63 |
64 |
82 |
83 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/templates/yihui.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Presentation Ninja"
3 | subtitle: "⚔
with xaringan"
4 | author: "Yihui Xie"
5 | date: "2016/12/12 (updated: `r Sys.Date()`)"
6 | output:
7 | xaringan::moon_reader:
8 | lib_dir: libs
9 | nature:
10 | highlightStyle: github
11 | highlightLines: true
12 | countIncrementalSlides: false
13 | ---
14 |
15 | ```{r setup, include=FALSE}
16 | options(htmltools.dir.version = FALSE)
17 | ```
18 |
19 | background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/be/Sharingan_triple.svg)
20 |
21 | ???
22 |
23 | Image credit: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Sharingan_triple.svg)
24 |
25 | ---
26 | class: center, middle
27 |
28 | # xaringan
29 |
30 | ### /ʃæ.'riŋ.ɡæn/
31 |
32 | ---
33 | class: inverse, center, middle
34 |
35 | # Get Started
36 |
37 | ---
38 |
39 | # Hello World
40 |
41 | Install the **xaringan** package from [Github](https://github.com/yihui/xaringan):
42 |
43 | ```{r eval=FALSE, tidy=FALSE}
44 | devtools::install_github("yihui/xaringan")
45 | ```
46 |
47 | --
48 |
49 | You are recommended to use the [RStudio IDE](https://www.rstudio.com/products/rstudio/), but you do not have to.
50 |
51 | - Create a new R Markdown document from the menu `File -> New File -> R Markdown -> From Template -> Ninja Presentation`;
1
52 |
53 | --
54 |
55 | - Click the `Knit` button to compile it;
56 |
57 | --
58 |
59 | - or use the [RStudio Addin](https://rstudio.github.io/rstudioaddins/)
2 "Infinite Moon Reader" to live preview the slides (every time you update and save the Rmd document, the slides will be automatically reloaded in RStudio Viewer.
60 |
61 | .footnote[
62 | [1] 中文用户请看[这份教程](http://slides.yihui.name/xaringan/zh-CN.html)
63 |
64 | [2] See [#2](https://github.com/yihui/xaringan/issues/2) if you do not see the template or addin in RStudio.
65 | ]
66 |
67 | ---
68 | background-image: url(`r xaringan:::karl`)
69 | background-position: 50% 50%
70 | class: center, bottom, inverse
71 |
72 | # You only live once!
73 |
74 | ---
75 |
76 | # Hello Ninja
77 |
78 | As a presentation ninja, you certainly should not be satisfied by the "Hello World" example. You need to understand more about two things:
79 |
80 | 1. The [remark.js](https://remarkjs.com) library;
81 |
82 | 1. The **xaringan** package;
83 |
84 | Basically **xaringan** injected the chakra of R Markdown (minus Pandoc) into **remark.js**. The slides are rendered by remark.js in the web browser, and the Markdown source needed by remark.js is generated from R Markdown (**knitr**).
85 |
86 | ---
87 |
88 | # remark.js
89 |
90 | You can see an introduction of remark.js from [its homepage](https://remarkjs.com). You should read the [remark.js Wiki](https://github.com/gnab/remark/wiki) at least once to know how to
91 |
92 | - create a new slide (Markdown syntax
* and slide properties);
93 |
94 | - format a slide (e.g. text alignment);
95 |
96 | - configure the slideshow;
97 |
98 | - and use the presentation (keyboard shortcuts).
99 |
100 | It is important to be familiar with remark.js before you can understand the options in **xaringan**.
101 |
102 | .footnote[[*] It is different with Pandoc's Markdown! It is limited but should be enough for presentation purposes. Come on... You do not need a slide for the Table of Contents! Well, the Markdown support in remark.js [may be improved](https://github.com/gnab/remark/issues/142) in the future.]
103 |
104 | ---
105 | background-image: url(`r xaringan:::karl`)
106 | background-size: cover
107 | class: center, bottom, inverse
108 |
109 | # I was so happy to have discovered remark.js!
110 |
111 | ---
112 | class: inverse, middle, center
113 |
114 | # Using xaringan
115 |
116 | ---
117 |
118 | # xaringan
119 |
120 | Provides an R Markdown output format `xaringan::moon_reader` as a wrapper for remark.js, and you can use it in the YAML metadata, e.g.
121 |
122 | ```yaml
123 | ---
124 | title: "A Cool Presentation"
125 | output:
126 | xaringan::moon_reader:
127 | yolo: true
128 | nature:
129 | autoplay: 30000
130 | ---
131 | ```
132 |
133 | See the help page `?xaringan::moon_reader` for all possible options that you can use.
134 |
135 | ---
136 |
137 | # remark.js vs xaringan
138 |
139 | Some differences between using remark.js (left) and using **xaringan** (right):
140 |
141 | .pull-left[
142 | 1. Start with a boilerplate HTML file;
143 |
144 | 1. Plain Markdown;
145 |
146 | 1. Write JavaScript to autoplay slides;
147 |
148 | 1. Manually configure MathJax;
149 |
150 | 1. Highlight code with `*`;
151 |
152 | 1. Edit Markdown source and refresh browser to see updated slides;
153 | ]
154 |
155 | .pull-right[
156 | 1. Start with an R Markdown document;
157 |
158 | 1. R Markdown (can embed R/other code chunks);
159 |
160 | 1. Provide an option `autoplay`;
161 |
162 | 1. MathJax just works;
*
163 |
164 | 1. Highlight code with `{{}}`;
165 |
166 | 1. The RStudio addin "Infinite Moon Reader" automatically refreshes slides on changes;
167 | ]
168 |
169 | .footnote[[*] Not really. See next page.]
170 |
171 | ---
172 |
173 | # Math Expressions
174 |
175 | You can write LaTeX math expressions inside a pair of dollar signs, e.g. $\alpha+\beta$ renders $\alpha+\beta$. You can use the display style with double dollar signs:
176 |
177 | ```
178 | $$\bar{X}=\frac{1}{n}\sum_{i=1}^nX_i$$
179 | ```
180 |
181 | $$\bar{X}=\frac{1}{n}\sum_{i=1}^nX_i$$
182 |
183 | Limitations:
184 |
185 | 1. The source code of a LaTeX math expression must be in one line, unless it is inside a pair of double dollar signs, in which case the starting `$$` must appear in the very beginning of a line, followed immediately by a non-space character, and the ending `$$` must be at the end of a line, led by a non-space character;
186 |
187 | 1. There should not be spaces after the opening `$` or before the closing `$`.
188 |
189 | 1. Math does not work on the title slide (see [#61](https://github.com/yihui/xaringan/issues/61) for a workaround).
190 |
191 | ---
192 |
193 | # R Code
194 |
195 | ```{r comment='#'}
196 | # a boring regression
197 | fit = lm(dist ~ 1 + speed, data = cars)
198 | coef(summary(fit))
199 | dojutsu = c('地爆天星', '天照', '加具土命', '神威', '須佐能乎', '無限月読')
200 | grep('天', dojutsu, value = TRUE)
201 | ```
202 |
203 | ---
204 |
205 | # R Plots
206 |
207 | ```{r cars, fig.height=4, dev='svg'}
208 | par(mar = c(4, 4, 1, .1))
209 | plot(cars, pch = 19, col = 'darkgray', las = 1)
210 | abline(fit, lwd = 2)
211 | ```
212 |
213 | ---
214 |
215 | # Tables
216 |
217 | If you want to generate a table, make sure it is in the HTML format (instead of Markdown or other formats), e.g.,
218 |
219 | ```{r}
220 | knitr::kable(head(iris), format = 'html')
221 | ```
222 |
223 | ---
224 |
225 | # HTML Widgets
226 |
227 | I have not thoroughly tested HTML widgets against **xaringan**. Some may work well, and some may not. It is a little tricky.
228 |
229 | Similarly, the Shiny mode (`runtime: shiny`) does not work. I might get these issues fixed in the future, but these are not of high priority to me. I never turn my presentation into a Shiny app. When I need to demonstrate more complicated examples, I just launch them separately. It is convenient to share slides with other people when they are plain HTML/JS applications.
230 |
231 | See the next page for two HTML widgets.
232 |
233 | ---
234 |
235 | ```{r out.width='100%', fig.height=6, eval=require('leaflet')}
236 | library(leaflet)
237 | leaflet() %>% addTiles() %>% setView(-93.65, 42.0285, zoom = 17)
238 | ```
239 |
240 | ---
241 |
242 | ```{r eval=require('DT'), tidy=FALSE}
243 | DT::datatable(
244 | head(iris, 10),
245 | fillContainer = FALSE, options = list(pageLength = 8)
246 | )
247 | ```
248 |
249 | ---
250 |
251 | # Some Tips
252 |
253 | - When you use the "Infinite Moon Reader" addin in RStudio, your R session will be blocked by default. You can click the red button on the right of the console to stop serving the slides, or use the _daemonized_ mode so that it does not block your R session. To do the latter, you can set the option
254 |
255 | ```r
256 | options(servr.daemon = TRUE)
257 | ```
258 |
259 | in your current R session, or in `~/.Rprofile` so that it is applied to all future R sessions. I do the latter by myself.
260 |
261 | To know more about the web server, see the [**servr**](https://github.com/yihui/servr) package.
262 |
263 | --
264 |
265 | - Do not forget to try the `yolo` option of `xaringan::moon_reader`.
266 |
267 | ```yaml
268 | output:
269 | xaringan::moon_reader:
270 | yolo: true
271 | ```
272 |
273 | ---
274 |
275 | # Some Tips
276 |
277 | - Slides can be automatically played if you set the `autoplay` option under `nature`, e.g. go to the next slide every 30 seconds in a lightning talk:
278 |
279 | ```yaml
280 | output:
281 | xaringan::moon_reader:
282 | nature:
283 | autoplay: 30000
284 | ```
285 |
286 | --
287 |
288 | - A countdown timer can be added to every page of the slides using the `countdown` option under `nature`, e.g. if you want to spend one minute on every page when you give the talk, you can set:
289 |
290 | ```yaml
291 | output:
292 | xaringan::moon_reader:
293 | nature:
294 | countdown: 60000
295 | ```
296 |
297 | Then you will see a timer counting down from `01:00`, to `00:59`, `00:58`, ... When the time is out, the timer will continue but the time turns red.
298 |
299 | ---
300 |
301 | # Some Tips
302 |
303 | - The title slide is created automatically by **xaringan**, but it is just another remark.js slide added before your other slides.
304 |
305 | The title slide is set to `class: center, middle, inverse, title-slide` by default. You can change the classes applied to the title slide with the `titleSlideClass` option of `nature` (`title-slide` is always applied).
306 |
307 | ```yaml
308 | output:
309 | xaringan::moon_reader:
310 | nature:
311 | titleSlideClass: [top, left, inverse]
312 | ```
313 |
314 | --
315 |
316 | - If you'd like to create your own title slide, disable **xaringan**'s title slide with the `seal = FALSE` option of `moon_reader`.
317 |
318 | ```yaml
319 | output:
320 | xaringan::moon_reader:
321 | seal: false
322 | ```
323 |
324 | ---
325 |
326 | # Some Tips
327 |
328 | - There are several ways to build incremental slides. See [this presentation](https://slides.yihui.name/xaringan/incremental.html) for examples.
329 |
330 | - The option `highlightLines: true` of `nature` will highlight code lines that start with `*`, or are wrapped in `{{ }}`, or have trailing comments `#<<`;
331 |
332 | ```yaml
333 | output:
334 | xaringan::moon_reader:
335 | nature:
336 | highlightLines: true
337 | ```
338 |
339 | See examples on the next page.
340 |
341 | ---
342 |
343 | # Some Tips
344 |
345 |
346 | .pull-left[
347 | An example using a leading `*`:
348 |
349 | ```r
350 | if (TRUE) {
351 | ** message("Very important!")
352 | }
353 | ```
354 | Output:
355 | ```r
356 | if (TRUE) {
357 | * message("Very important!")
358 | }
359 | ```
360 |
361 | This is invalid R code, so it is a plain fenced code block that is not executed.
362 | ]
363 |
364 | .pull-right[
365 | An example using `{{}}`:
366 |
367 | `r ''````{r tidy=FALSE}
368 | if (TRUE) {
369 | *{{ message("Very important!") }}
370 | }
371 | ```
372 | Output:
373 | ```{r tidy=FALSE}
374 | if (TRUE) {
375 | {{ message("Very important!") }}
376 | }
377 | ```
378 |
379 | It is valid R code so you can run it. Note that `{{}}` can wrap an R expression of multiple lines.
380 | ]
381 |
382 | ---
383 |
384 | # Some Tips
385 |
386 | An example of using the trailing comment `#<<` to highlight lines:
387 |
388 | ````markdown
389 | `r ''````{r tidy=FALSE}
390 | library(ggplot2)
391 | ggplot(mtcars) +
392 | aes(mpg, disp) +
393 | geom_point() + #<<
394 | geom_smooth() #<<
395 | ```
396 | ````
397 |
398 | Output:
399 |
400 | ```{r tidy=FALSE, eval=FALSE}
401 | library(ggplot2)
402 | ggplot(mtcars) +
403 | aes(mpg, disp) +
404 | geom_point() + #<<
405 | geom_smooth() #<<
406 | ```
407 |
408 | ---
409 |
410 | # Some Tips
411 |
412 | When you enable line-highlighting, you can also use the chunk option `highlight.output` to highlight specific lines of the text output from a code chunk. For example, `highlight.output = TRUE` means highlighting all lines, and `highlight.output = c(1, 3)` means highlighting the first and third line.
413 |
414 | ````md
415 | `r ''````{r, highlight.output=c(1, 3)}
416 | head(iris)
417 | ```
418 | ````
419 |
420 | ```{r, highlight.output=c(1, 3), echo=FALSE}
421 | head(iris)
422 | ```
423 |
424 | Question: what does `highlight.output = c(TRUE, FALSE)` mean? (Hint: think about R's recycling of vectors)
425 |
426 | ---
427 |
428 | # Some Tips
429 |
430 | - To make slides work offline, you need to download a copy of remark.js in advance, because **xaringan** uses the online version by default (see the help page `?xaringan::moon_reader`).
431 |
432 | - You can use `xaringan::summon_remark()` to download the latest or a specified version of remark.js. By default, it is downloaded to `libs/remark-latest.min.js`.
433 |
434 | - Then change the `chakra` option in YAML to point to this file, e.g.
435 |
436 | ```yaml
437 | output:
438 | xaringan::moon_reader:
439 | chakra: libs/remark-latest.min.js
440 | ```
441 |
442 | - If you used Google fonts in slides (the default theme uses _Yanone Kaffeesatz_, _Droid Serif_, and _Source Code Pro_), they won't work offline unless you download or install them locally. The Heroku app [google-webfonts-helper](https://google-webfonts-helper.herokuapp.com/fonts) can help you download fonts and generate the necessary CSS.
443 |
444 | ---
445 |
446 | # Macros
447 |
448 | - remark.js [allows users to define custom macros](https://github.com/yihui/xaringan/issues/80) (JS functions) that can be applied to Markdown text using the syntax `![:macroName arg1, arg2, ...]` or ``. For example, before remark.js initializes the slides, you can define a macro named `scale`:
449 |
450 | ```js
451 | remark.macros.scale = function (percentage) {
452 | var url = this;
453 | return '

';
454 | };
455 | ```
456 |
457 | Then the Markdown text
458 |
459 | ```markdown
460 | 
461 | ```
462 |
463 | will be translated to
464 |
465 | ```html
466 |

467 | ```
468 |
469 | ---
470 |
471 | # Macros (continued)
472 |
473 | - To insert macros in **xaringan** slides, you can use the option `beforeInit` under the option `nature`, e.g.,
474 |
475 | ```yaml
476 | output:
477 | xaringan::moon_reader:
478 | nature:
479 | beforeInit: "macros.js"
480 | ```
481 |
482 | You save your remark.js macros in the file `macros.js`.
483 |
484 | - The `beforeInit` option can be used to insert arbitrary JS code before `remark.create()`. Inserting macros is just one of its possible applications.
485 |
486 | ---
487 |
488 | # CSS
489 |
490 | Among all options in `xaringan::moon_reader`, the most challenging but perhaps also the most rewarding one is `css`, because it allows you to customize the appearance of your slides using any CSS rules or hacks you know.
491 |
492 | You can see the default CSS file [here](https://github.com/yihui/xaringan/blob/master/inst/rmarkdown/templates/xaringan/resources/default.css). You can completely replace it with your own CSS files, or define new rules to override the default. See the help page `?xaringan::moon_reader` for more information.
493 |
494 | ---
495 |
496 | # CSS
497 |
498 | For example, suppose you want to change the font for code from the default "Source Code Pro" to "Ubuntu Mono". You can create a CSS file named, say, `ubuntu-mono.css`:
499 |
500 | ```css
501 | @import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
502 |
503 | .remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
504 | ```
505 |
506 | Then set the `css` option in the YAML metadata:
507 |
508 | ```yaml
509 | output:
510 | xaringan::moon_reader:
511 | css: ["default", "ubuntu-mono.css"]
512 | ```
513 |
514 | Here I assume `ubuntu-mono.css` is under the same directory as your Rmd.
515 |
516 | See [yihui/xaringan#83](https://github.com/yihui/xaringan/issues/83) for an example of using the [Fira Code](https://github.com/tonsky/FiraCode) font, which supports ligatures in program code.
517 |
518 | ---
519 |
520 | # Themes
521 |
522 | Don't want to learn CSS? Okay, you can use some user-contributed themes. A theme typically consists of two CSS files `foo.css` and `foo-fonts.css`, where `foo` is the theme name. Below are some existing themes:
523 |
524 | ```{r}
525 | names(xaringan:::list_css())
526 | ```
527 |
528 | ---
529 |
530 | # Themes
531 |
532 | To use a theme, you can specify the `css` option as an array of CSS filenames (without the `.css` extensions), e.g.,
533 |
534 | ```yaml
535 | output:
536 | xaringan::moon_reader:
537 | css: [default, metropolis, metropolis-fonts]
538 | ```
539 |
540 | If you want to contribute a theme to **xaringan**, please read [this blog post](https://yihui.name/en/2017/10/xaringan-themes).
541 |
542 | ---
543 | class: inverse, middle, center
544 | background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/39/Naruto_Shiki_Fujin.svg)
545 | background-size: contain
546 |
547 | # Naruto
548 |
549 | ---
550 | background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/be/Sharingan_triple.svg)
551 | background-size: 100px
552 | background-position: 90% 8%
553 |
554 | # Sharingan
555 |
556 | The R package name **xaringan** was derived
1 from **Sharingan**, a dōjutsu in the Japanese anime _Naruto_ with two abilities:
557 |
558 | - the "Eye of Insight"
559 |
560 | - the "Eye of Hypnotism"
561 |
562 | I think a presentation is basically a way to communicate insights to the audience, and a great presentation may even "hypnotize" the audience.
2,3
563 |
564 | .footnote[
565 | [1] In Chinese, the pronounciation of _X_ is _Sh_ /ʃ/ (as in _shrimp_). Now you should have a better idea of how to pronounce my last name _Xie_.
566 |
567 | [2] By comparison, bad presentations only put the audience to sleep.
568 |
569 | [3] Personally I find that setting background images for slides is a killer feature of remark.js. It is an effective way to bring visual impact into your presentations.
570 | ]
571 |
572 | ---
573 |
574 | # Naruto terminology
575 |
576 | The **xaringan** package borrowed a few terms from Naruto, such as
577 |
578 | - [Sharingan](http://naruto.wikia.com/wiki/Sharingan) (写輪眼; the package name)
579 |
580 | - The [moon reader](http://naruto.wikia.com/wiki/Moon_Reader) (月読; an attractive R Markdown output format)
581 |
582 | - [Chakra](http://naruto.wikia.com/wiki/Chakra) (查克拉; the path to the remark.js library, which is the power to drive the presentation)
583 |
584 | - [Nature transformation](http://naruto.wikia.com/wiki/Nature_Transformation) (性質変化; transform the chakra by setting different options)
585 |
586 | - The [infinite moon reader](http://naruto.wikia.com/wiki/Infinite_Tsukuyomi) (無限月読; start a local web server to continuously serve your slides)
587 |
588 | - The [summoning technique](http://naruto.wikia.com/wiki/Summoning_Technique) (download remark.js from the web)
589 |
590 | You can click the links to know more about them if you want. The jutsu "Moon Reader" may seem a little evil, but that does not mean your slides are evil.
591 |
592 | ---
593 |
594 | class: center
595 |
596 | # Hand seals (印)
597 |
598 | Press `h` or `?` to see the possible ninjutsu you can use in remark.js.
599 |
600 | 
601 |
602 | ---
603 |
604 | class: center, middle
605 |
606 | # Thanks!
607 |
608 | Slides created via the R package [**xaringan**](https://github.com/yihui/xaringan).
609 |
610 | The chakra comes from [remark.js](https://remarkjs.com), [**knitr**](http://yihui.name/knitr), and [R Markdown](https://rmarkdown.rstudio.com).
611 |
--------------------------------------------------------------------------------