Ajout d'une extension

This commit is contained in:
Gauvain Boiché
2020-04-04 18:27:27 +02:00
parent c3ed8cc1c1
commit 3a964fe237
387 changed files with 58921 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
<div data-shop-carousel-data="true"
data-arrows="{{ SHOP_CAROUSEL_ARROWS ? 'true' : 'false' }}"
data-dots="{{ SHOP_CAROUSEL_DOTS ? 'true' : 'false' }}"
data-fade="{{ SHOP_CAROUSEL_FADE ? 'true' : 'false' }}"
data-autoplay="{{ SHOP_CAROUSEL_PLAY ? 'true' : 'false' }}"
data-autoplay-speed="{{ SHOP_CAROUSEL_PLAY_SPEED }}"
data-speed="{{ SHOP_CAROUSEL_SPEED }}"
></div>

View File

@@ -0,0 +1,235 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block includes %}
{% INCLUDECSS '@phpbbstudio_ass/ass_common.css' %}
{% INCLUDEJS '@phpbbstudio_ass/js/ass_common.js' %}
{% endblock %}
{% block nav %}
{% for category in ass_shop_categories %}
<li>
<a class="aps-list-item{{ category.S_SELECTED ? ' aps-list-active' }}" href="{{ category.U_VIEW }}" title="{{ category.TITLE }}">
{% if category.ICON %}<i class="icon {{ category.ICON }} fa-fw" aria-hidden="true"></i>{% endif %}
<span class="sr-only">{{ category.TITLE }}</span>
</a>
</li>
{% endfor %}
{% endblock %}
{% block main %}
<div class="aps-row">
<div class="aps-col s12">
<div class="shop-title">
<h1 class="aps-no-mar shop-text-darkgray">{{ TITLE }}</h1>
</div>
</div>
{% if not S_ACTIVE %}
<div class="aps-col s12">
<div class="aps-button-red">
<strong>{{ lang('ASS_CATEGORY_INACTIVE') }}</strong>
</div>
</div>
{% endif %}
{% if DESC_HTML %}
{% if ICON %}
<div class="aps-col s2">
<div class="aps-panel aps-center">
<div class="aps-panel-content">
<i class="fa {{ ICON }} fa-fw fa-5x icon-aps-blue" aria-hidden="true"></i>
</div>
</div>
</div>
{% endif %}
<div class="aps-col s{{ ICON ? 10 : 12 }}">
<div class="aps-panel">
<div class="aps-panel-content content">
{{ DESC_HTML }}
</div>
</div>
</div>
{% endif %}
</div>
<div class="aps-row">
{% for item in ass_items %}
<div class="aps-col s6 m{{ T_PANEL_SIZE }}">
{{ include('@phpbbstudio_ass/ass_item_panel.html') }}
</div>
{% else %}
<div class="aps-col s12">
<div class="aps-panel">
<div class="aps-panel-content aps-center">
<strong class="error">{{ lang('ASS_ITEMS_NONE') }}</strong>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="aps-row">
<div class="aps-col s2">
<form class="aps-form" method="get" action="{{ U_VIEW }}">
<div class="shop-block dropdown-container dropdown-container-left dropdown-up dropdown-right dropdown-button-control">
<span class="shop-block aps-button-blue aps-center dropdown-trigger" title="{{ lang('SORT_OPTIONS') }}">
<i class="icon fa-sort-amount-asc fa-fw" aria-hidden="true"></i>
</span>
<div class="dropdown hidden shop-category-dropdown">
<div class="pointer"><div class="pointer-inner"></div></div>
<div class="dropdown-contents">
<fieldset>
<div class="aps-row">
<div class="aps-col s4">
<label for="title">
{{ lang('ASS_ITEM_TITLE') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<input class="full" id="title" name="title" type="text" value="{{ SORT_TITLE }}">
</div>
<div class="aps-col s4">
<label for="type">
{{ lang('ASS_ITEM_TYPE') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<select class="full" id="type" name="type">
{% for value, option in SORT_TYPE_ARRAY %}
<option value="{{ value }}"{{ value == SORT_TYPE ? ' selected' }}>{{ lang(option) }}</option>
{% endfor %}
</select>
</div>
<div class="aps-col s4">
<label for="above">
{{ lang('ASS_PRICE_ABOVE') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<input class="full" id="above" name="above" type="number" step="{{ aps_step() }}" value="{{ SORT_ABOVE }}">
</div>
<div class="aps-col s4">
<label for="below">
{{ lang('ASS_PRICE_BELOW') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<input class="full" id="below" name="below" type="number" step="{{ aps_step() }}" value="{{ SORT_BELOW }}">
</div>
<div class="aps-col s4">
<label for="sale">
{{ lang('ASS_ON_SALE') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8 aps-center">
<div class="aps-row">
<label class="aps-col s4 aps-no-mar shop-no-pad-left">
<input class="aps-bool" id="sale" name="sale" type="radio" value="1"{{ SORT_SALE == 1 ? ' checked' }}>
<span class="aps-button-green shop-block"><i class="icon fa-check fa-fw shop-text-indent-3" aria-hidden="true"></i></span>
</label>
<label class="aps-col s4 aps-no-mar shop-no-pad-left">
<input class="aps-bool" name="sale" type="radio" value="-1"{{ SORT_SALE == -1 ? ' checked' }}>
<span class="aps-button-red shop-block"><i class="icon fa-times fa-fw shop-text-indent-3" aria-hidden="true"></i></span>
</label>
<label class="aps-col s4 aps-no-mar shop-no-pad-left">
<input class="aps-bool" name="sale" type="radio" value="0"{{ not SORT_SALE ? ' checked' }}>
<span class="aps-button-blue shop-block"><i class="icon fa-minus fa-fw shop-text-indent-3" aria-hidden="true"></i></span>
</label>
</div>
</div>
<div class="aps-col s4 aps-no-mar-bot">
<label for="gift">
{{ lang('ASS_GIFTABLE') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8 aps-no-mar-bot aps-center">
<div class="aps-row">
<label class="aps-col s4 aps-no-mar shop-no-pad-left">
<input class="aps-bool" id="gift" name="gift" type="radio" value="1"{{ SORT_GIFT == 1 ? ' checked' }}>
<span class="aps-button-green shop-block"><i class="icon fa-check fa-fw shop-text-indent-3" aria-hidden="true"></i></span>
</label>
<label class="aps-col s4 aps-no-mar shop-no-pad-left">
<input class="aps-bool" name="gift" type="radio" value="-1"{{ SORT_GIFT == -1 ? ' checked' }}>
<span class="aps-button-red shop-block"><i class="icon fa-times fa-fw shop-text-indent-3" aria-hidden="true"></i></span>
</label>
<label class="aps-col s4 aps-no-mar shop-no-pad-left">
<input class="aps-bool" name="gift" type="radio" value="0"{{ not SORT_GIFT ? ' checked' }}>
<span class="aps-button-blue shop-block"><i class="icon fa-minus fa-fw shop-text-indent-3" aria-hidden="true"></i></span>
</label>
</div>
</div>
<div class="aps-col s12 aps-no-mar">
<hr class="dashed">
</div>
<div class="aps-col s4">
<label for="display">
{{ lang('DISPLAY') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<select class="full" id="display" name="display">
{% for value, option in SORT_DAYS_ARRAY %}
<option value="{{ value }}"{{ value == SORT_DAYS ? ' selected' }}>{{ lang(option) }}</option>
{% endfor %}
</select>
</div>
<div class="aps-col s4">
<label for="sort">
{{ lang('SORT_BY') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<select class="full" id="sort" name="sort">
{% for value, option in SORT_SORT_ARRAY %}
<option value="{{ value }}"{{ value == SORT_SORT ? ' selected' }}>{{ lang(option.title) }}</option>
{% endfor %}
</select>
</div>
<div class="aps-col s4 aps-no-mar-bot">
<label for="direction">
{{ lang('SORT_DIRECTION') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8 aps-no-mar-bot">
<select class="full" id="direction" name="direction">
{% for value, option in SORT_DIR_ARRAY %}
<option value="{{ value }}"{{ value == SORT_DIR ? ' selected' }}>{{ lang(option.title) }}</option>
{% endfor %}
</select>
</div>
<div class="aps-col s12 aps-center aps-no-mar-bot">
<hr class="dashed">
<input class="aps-button-green" type="submit" value="{{ lang('GO') }}">
</div>
</div>
</fieldset>
</div>
</div>
</div>
</form>
</div>
<div class="aps-col s8">
{% if shop_pagination|length %}
{{ include('@phpbbstudio_ass/ass_pagination.html') }}
{% endif %}
</div>
<div class="aps-col s2">
<div class="aps-center shop-pagination-text">
{{ ITEMS_COUNT }}
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,3 @@
<form action="{{ S_CONFIRM_ACTION }}" method="post">
<p>{{ MESSAGE_TEXT }}</p>
</form>

View File

@@ -0,0 +1,70 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block includes %}
{% INCLUDECSS '@phpbbstudio_ass/ass_exception.css' %}
{% endblock %}
{% block nav %}
{% for category in ass_shop_categories %}
<li>
<a class="aps-list-item{{ category.S_SELECTED ? ' aps-list-active' }}" href="{{ category.U_VIEW }}" title="{{ category.TITLE }}">
{% if category.ICON %}<i class="icon {{ category.ICON }} fa-fw" aria-hidden="true"></i>{% endif %}
<span class="sr-only">{{ category.TITLE }}</span>
</a>
</li>
{% endfor %}
{% endblock %}
{% block main %}
<div class="shop-exception">
<div class="aps-panel shop-exception-title">
<div class="aps-panel-content">
<h1>{{ lang('ASS_ERROR_TITLE', aps_name()) ~ lang('ELLIPSIS') }}</h1>
</div>
<div class="shop-exception-code">
<span>{{ EXCEPTION_CODE }}</span>
</div>
</div>
<div class="aps-panel shop-exception-text">
<div class="aps-panel-content">
<p class="aps-no-mar">{{ EXCEPTION_TEXT }}</p>
</div>
{% if EXCEPTION_DESC %}
<div class="aps-panel-content">
<p class="aps-no-mar">{{ EXCEPTION_DESC }}</p>
</div>
{% endif %}
<div class="aps-panel-content aps-center">
<a class="aps-button-blue" href="{{ U_INDEX }}">{{ lang('FORUM_INDEX') }}</a>
<a class="aps-button-blue" href="{{ path('phpbbstudio_ass_shop') }}">{{ lang('ASS_SHOP_INDEX') }}</a>
</div>
</div>
<div class="shop-exception-pot">{{ include('@phpbbstudio_ass/images/gold-pot.svg') }}</div>
<div class="shop-exception-rainbow">{% for i in 1..5 %}<span></span>{% endfor %}</div>
<div class="shop-exception-tree">{{ include('@phpbbstudio_ass/images/tree.svg') }}</div>
<div class="shop-exception-trees">{{ include('@phpbbstudio_ass/images/trees.svg') }}</div>
<div class="shop-exception-mountain">{{ include('@phpbbstudio_ass/images/mountain-summit.svg') }}</div>
<div class="shop-exception-mountain-left">{{ include('@phpbbstudio_ass/images/mountain-summit.svg') }}</div>
<div class="shop-exception-mountain-right">{{ include('@phpbbstudio_ass/images/rising-graph.svg') }}</div>
<i class="icon fa-male fa-fw"></i>
<i class="icon fa-fw shop-icons"></i>
<i class="icon fa-comment fa-fw fa-flip-horizontal"></i>
<i class="icon fa-map-signs fa-fw"></i>
<span class="fa-trees left">
<i class="icon fa-tree fa-fw"></i>
<i class="icon fa-tree fa-fw"></i>
<i class="icon fa-tree fa-fw"></i>
</span>
<span class="fa-trees">
<i class="icon fa-tree fa-fw"></i>
<i class="icon fa-tree fa-fw"></i>
</span>
<span class="fa-trees right">
<i class="icon fa-tree fa-fw"></i>
<i class="icon fa-tree fa-fw"></i>
<i class="icon fa-tree fa-fw"></i>
</span>
</div>
{% endblock %}

View File

@@ -0,0 +1,156 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block includes %}
{% INCLUDECSS '@phpbbstudio_ass/ass_common.css' %}
{% endblock %}
{% block main %}
<div class="shop-title shop-mar-bot">
<h1 class="aps-no-mar shop-text-darkgray">{{ lang('ASS_HISTORY') }}</h1>
</div>
{% for log in ass_logs %}
<div class="aps-panel shop-mar-bot">
<div class="aps-panel-header">
<div class="aps-row">
<div class="aps-col s8 aps-no-mar">
{% if log.U_CATEGORY %}
<a class="shop-text-darkgray shop-panel-header-link" href="{{ log.U_CATEGORY }}" data-item-title="{{ log.CATEGORY_TITLE }}">
{{ log.CATEGORY_TITLE }}
</a>
{% else %}
<span class="shop-text-darkgray shop-panel-header-link">{{ log.CATEGORY_TITLE }}</span>
{% endif %}
<i class="icon fa-angle-right fa-fw icon-aps-blue" aria-hidden="true"></i>
{% if log.U_ITEM %}
<a class="shop-text-darkgray shop-panel-header-link shop-bold" href="{{ log.U_ITEM }}" data-item-title="{{ log.ITEM_TITLE }}">
{{ log.ITEM_TITLE }}
</a>
{% else %}
<span class="shop-text-darkgray shop-panel-header-link shop-bold">
{{ log.ITEM_TITLE }}
</span>
{% endif %}
</div>
<div class="aps-col s4 aps-no-mar shop-text-right shop-text-lightgray">
{{ log.LOG_TIME }}
</div>
</div>
</div>
<div class="aps-panel-content">
<div class="aps-row">
<div class="aps-col s12 m6 aps-no-mar shop-darken-span">
{% if log.S_PURCHASE %}
{% if log.RECIPIENT %}
{% if log.S_GIFT_RECEIVED %}
<span>{{ lang('ASS_LOG_ITEM_RECEIVED', log.USER) }}</span>
{% else %}
<span>{{ lang('ASS_LOG_ITEM_GIFTED', log.RECIPIENT) }}</span>
{% endif %}
{% else %}
<span>{{ lang('ASS_LOG_ITEM_PURCHASED') }}</span>
{% endif %}
{% else %}
<span>{{ lang('ASS_LOG_ITEM_USED') ~ lang('COLON') }}</span> {{ log.LOG_ACTION }}
{% endif %}
</div>
<div class="aps-col s4 m2 aps-no-mar aps-center">{{ aps_display(log.POINTS_OLD, false) }}</div>
<div class="aps-col s4 m2 aps-no-mar aps-center{{ log.POINTS_SUM ? ' aps-negative' }}">{{ aps_display(log.POINTS_SUM, false) }}</div>
<div class="aps-col s4 m2 aps-no-mar aps-center">{{ aps_display(log.POINTS_NEW, false) }}</div>
</div>
</div>
</div>
{% else %}
<div class="aps-panel aps-center">
<div class="aps-panel-content">
<p class="aps-no-mar shop-padding error">{{ lang('ASS_HISTORY_EMPTY') ~ lang('ELLIPSIS') }}</p>
</div>
<div class="aps-panel-footer">
<a class="aps-button-green shop-button-active" href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP_INDEX') }}">
<i class="icon {{ aps_config('ass_shop_icon') }} fa-fw" aria-hidden="true"></i>
<span>{{ lang('ASS_SHOP_INDEX') }}</span>
</a>
</div>
</div>
{% endfor %}
{% if ass_logs|length %}
<div class="aps-row">
<div class="aps-col s2">
<form class="aps-form" method="get" action="{{ U_VIEW }}">
<div class="shop-block dropdown-container dropdown-container-left dropdown-up dropdown-right dropdown-button-control">
<span class="shop-block aps-button-blue aps-center dropdown-trigger" title="{{ lang('SORT_OPTIONS') }}">
<i class="icon fa-sort-amount-asc fa-fw" aria-hidden="true"></i>
</span>
<div class="dropdown hidden shop-category-dropdown">
<div class="pointer"><div class="pointer-inner"></div></div>
<div class="dropdown-contents">
<fieldset>
<div class="aps-row">
<div class="aps-col s4">
<label for="display">
{{ lang('DISPLAY') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<select id="display" name="display">
{% for value, option in SORT_DISPLAY_ARRAY %}
<option value="{{ value }}"{{ value == SORT_DISPLAY ? ' selected' }}>{{ lang(option.title) }}</option>
{% endfor %}
</select>
</div>
<div class="aps-col s4">
<label for="sort">
{{ lang('SORT_BY') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8">
<select class="full" id="sort" name="sort">
{% for value, option in SORT_SORT_ARRAY %}
<option value="{{ value }}"{{ value == SORT_SORT ? ' selected' }}>{{ lang(option.title) }}</option>
{% endfor %}
</select>
</div>
<div class="aps-col s4 aps-no-mar-bot">
<label for="direction">
{{ lang('SORT_DIRECTION') ~ lang('COLON') }}
</label>
</div>
<div class="aps-col s8 aps-no-mar-bot">
<select class="full" id="direction" name="direction">
{% for value, option in SORT_DIR_ARRAY %}
<option value="{{ value }}"{{ value == SORT_DIR ? ' selected' }}>{{ lang(option.title) }}</option>
{% endfor %}
</select>
</div>
<div class="aps-col s12 aps-center aps-no-mar-bot">
<hr class="dashed">
<input class="aps-button-green" type="submit" value="{{ lang('GO') }}">
</div>
</div>
</fieldset>
</div>
</div>
</div>
</form>
</div>
<div class="aps-col s8">
{% if shop_pagination|length %}
{{ include('@phpbbstudio_ass/ass_pagination.html') }}
{% endif %}
</div>
<div class="aps-col s2">
<div class="aps-center shop-pagination-text">
{{ TOTAL_LOGS }}
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,136 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block includes %}
{% INCLUDECSS '@phpbbstudio_ass/jquery-ui.min.css' %}
{% INCLUDEJS '@phpbbstudio_ass/js/jquery-ui.min.js' %}
{% INCLUDEJS '@phpbbstudio_ass/js/sketch.js' %}
{% INCLUDECSS '@phpbbstudio_ass/ass_common.css' %}
{% INCLUDEJS '@phpbbstudio_ass/js/ass_common.js' %}
{% EVENT phpbbstudio_ass_includes_inventory %}
{% endblock %}
{% block nav %}
{% for category in ass_shop_categories %}
<li>
<a class="aps-list-item{{ category.S_SELECTED ? ' aps-list-active' }}" href="{{ category.U_VIEW }}" title="{{ category.TITLE }}">
{% if category.ICON %}<i class="icon {{ category.ICON }} fa-fw" aria-hidden="true"></i>{% endif %}
<span class="sr-only">{{ category.TITLE }}</span>
</a>
</li>
{% endfor %}
{% endblock %}
{% block nav_right %}
<li>
<a class="aps-list-item" href="{{ path('phpbbstudio_ass_history') }}" title="{{ lang('ASS_HISTORY') }}">
<i class="icon fa-history fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_HISTORY') }}</span>
</a>
</li>
{% endblock %}
{% block main %}
{% if ass_categories|length %}
<div class="shop-inventory-overlay"></div>
<div class="aps-row">
<div class="aps-col m5 shop-inventory-list{{ ITEM_INFO ? ' shop-inventory-with-item' }} aps-no-mar-bot">
<div class="aps-panel-content">
{% for category in ass_categories %}
<div class="shop-title shop-mar-bot">
<h1 class="aps-no-mar shop-text-large shop-text-darkgray">{{ category.TITLE }}</h1>
</div>
{% for batch in category.items|batch(3) %}
<div class="aps-row shop-inventory-row">
{% for item in batch %}
<div class="aps-col s12 m4 shop-fake-min-width">
<section class="shop-inventory-panel">
<a class="aps-panel shop-inventory-link" href="{{ item.U_INVENTORY }}">
{% if item.S_TYPE_ERROR %}
<i class="icon fa-exclamation-triangle icon-white shop-panel-icon shop-panel-icon-tiny shop-panel-icon-red"></i>
{% elseif item.STACK_COUNT > 1 %}
<span class="icon icon-white shop-panel-icon shop-panel-icon-tiny shop-panel-icon-purple"><strong class="shop-inventory-stack">{{ item.STACK_COUNT }}</strong></span>
{% elseif item.S_HAS_EXPIRED %}
<i class="icon fa-hourglass-end icon-white shop-panel-icon shop-panel-icon-tiny shop-panel-icon-red"></i>
{% elseif item.S_WILL_EXPIRE %}
<i class="icon fa-hourglass-half icon-white shop-panel-icon shop-panel-icon-tiny shop-panel-icon-orange"></i>
{% elseif item.S_GIFTED %}
<i class="icon {{ aps_config('ass_gift_icon') }} icon-white shop-panel-icon shop-panel-icon-tiny shop-panel-icon-blue"></i>
{% endif %}
<div class="aps-panel-content {{ item.BACKGROUND_SRC ? 'shop-panel-background' : 'shop-vertical' }}"{% if item.BACKGROUND_SRC %} style="background-image: url({{ item.BACKGROUND_SRC }})"{% endif %}>
{% if not item.BACKGROUND_SRC %}
<i class="icon {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-fw shop-text-indent-10 icon-xl icon-lightgray"></i>
{% endif %}
</div>
<div class="aps-panel-footer shop-bold shop-text-small shop-text-darkgray shop-text-ellipsis" title="{{ item.TITLE }}">
{{ item.TITLE }}
</div>
</a>
{{ include('@phpbbstudio_ass/ass_item_inventory.html') }}
</section>
</div>
{% endfor %}
</div>
{% endfor %}
{% endfor %}
</div>
<div class="aps-panel-footer aps-row aps-center">
<div class="aps-col s3 aps-no-mar shop-no-pad">
<a class="aps-button-blue shop-block" href="{{ U_VIEW_SHOP }}" title="{{ L_VIEW_SHOP }}">
<i class="fa {{ aps_config('ass_shop_icon') }} fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_SHOP_INDEX') }}</span>
</a>
</div>
<div class="aps-col s1"></div>
<div class="aps-col s2 aps-no-mar shop-no-pad" title="{{ aps_name() }}">
{{ aps_icon() }}
<strong class="shop-block">{{ aps_display(user.data.user_points, false) }}</strong>
</div>
<div class="aps-col s2 aps-no-mar shop-no-pad">
<i class="icon {{ T_SHOP_ICON }} fa-fw"></i>
<strong class="shop-block">{{ COUNT_TOTAL }}</strong>
</div>
<div class="aps-col s2 aps-no-mar shop-no-pad">
<i class="icon fa-hourglass-start fa-fw"></i>
<strong class="shop-block">{{ COUNT_EXPIRE }}</strong>
</div>
<div class="aps-col s2 aps-no-mar shop-no-pad">
<i class="icon {{ aps_config('ass_gift_icon') }} fa-fw"></i>
<strong class="shop-block">{{ COUNT_GIFTS }}</strong>
</div>
</div>
</div>
<div class="aps-col m7 aps-no-mar-bot">
<div class="shop-inventory-info">
<div class="shop-inventory-proxy">
<div class="shop-inventory-card">
{{ aps_icon(true) }}
</div>
</div>
{% if ITEM_INFO %}
{{ include('@phpbbstudio_ass/ass_item_inventory.html', {item: ITEM_INFO, S_GIFT_ANIMATION: S_IS_GIFT, S_LOADED_ITEM: true}) }}
{% endif %}
</div>
</div>
</div>
{% else %}
<div class="aps-panel aps-center">
<div class="aps-panel-content">
<p class="aps-no-mar shop-padding error">{{ lang('ASS_ITEMS_NONE_INVENTORY') ~ lang('ELLIPSIS') }}</p>
</div>
<div class="aps-panel-footer">
<a class="aps-button-green shop-button-active" href="{{ U_VIEW_SHOP }}" title="{{ L_VIEW_SHOP }}">
<i class="icon {{ T_SHOP_ICON }} fa-fw" aria-hidden="true"></i>
<span>{{ L_VIEW_SHOP }}</span>
</a>
</div>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,286 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block includes %}
{% INCLUDEJS '@phpbbstudio_ass/js/slick.min.js' %}
{% INCLUDECSS '@phpbbstudio_ass/slick.css' %}
{% INCLUDECSS '@phpbbstudio_ass/ass_item.css' %}
{% INCLUDECSS '@phpbbstudio_ass/ass_common.css' %}
{% INCLUDEJS '@phpbbstudio_ass/js/ass_common.js' %}
{% endblock %}
{% block nav %}
{% for category in ass_shop_categories %}
<li>
<a class="aps-list-item{{ category.S_SELECTED ? ' aps-list-active' }}" href="{{ category.U_VIEW }}" title="{{ category.TITLE }}">
{% if category.ICON %}<i class="icon {{ category.ICON }} fa-fw" aria-hidden="true"></i>{% endif %}
<span class="sr-only">{{ category.TITLE }}</span>
</a>
</li>
{% endfor %}
{% endblock %}
{% block nav_right %}
<li class="shop-item-help-label">
<label class="aps-list-item shop-cursor-pointer" for="shop-item-help-input" title="{{ lang('ASS_ITEM_HELP') }}">
<i class="icon fa-question fa-fw icon-white" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_ITEM_HELP') }}</span>
</label>
</li>
{% endblock %}
{% block main %}
{{ include('@phpbbstudio_ass/ass_carousel.html') }}
<input class="shop-item-help-input" id="shop-item-help-input" type="checkbox" />
{% set delay = 3 %}
<div class="shop-item-help">
<div class="aps-row" data-shop-item="{{ ID }}">
{% if ICON %}
<div class="aps-col s2">
<div class="aps-panel aps-center shop-relative">
<span class="shop-item-helper bottom-right delay-{{ delay }}">{{ lang('ASS_ITEM_ICON') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content">
<i class="fa {{ ICON }} fa-3x icon-aps-blue shop-text-indent-10" aria-hidden="true"></i>
</div>
</div>
</div>
{% endif %}
<div class="aps-col s{{ ICON ? 10 : 12 }}">
<div class="shop-title shop-relative">
<span class="shop-item-helper bottom-left delay-{{ delay }}">{{ lang('ASS_ITEM_TITLE') }}</span>
{% set delay = delay + 1 %}
<h1 class="aps-no-mar shop-text-darkgray">{{ TITLE }}</h1>
</div>
</div>
{% if not S_ACTIVE %}
<div class="aps-col s12">
<div class="aps-button-red">
<strong>{{ lang('ASS_ITEM_INACTIVE') }}</strong>
</div>
</div>
{% endif %}
<div class="aps-col s12 m6">
<div class="aps-panel shop-relative">
<span class="shop-item-helper right delay-{{ delay }}">{{ lang('ASS_ITEM_IMAGE') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content aps-center shop-panel-height {{ BACKGROUND_SRC ? 'shop-panel-background' : 'shop-vertical shop-center' }}"{% if BACKGROUND_SRC %} style="background-image: url({{ BACKGROUND_SRC }})"{% endif %}>
{% if S_FEATURED and S_SALE and SHOP_PANEL_FEATURED_SALE_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_FEATURED_SALE_ICON }}"></i>
{% elseif S_FEATURED and SHOP_PANEL_FEATURED_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_FEATURED_ICON }}" title="{{ lang('ASS_FEATURED') }}"></i>
{% elseif S_SALE and SHOP_PANEL_SALE_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_SALE_ICON }}" title="{{ lang('ASS_ON_SALE') }}"></i>
{% endif %}
{% if not BACKGROUND_SRC %}
<i class="icon {{ aps_config('ass_no_image_icon') }} shop-text-indent-10 icon-xl icon-lightgray"></i>
{% endif %}
</div>
</div>
</div>
<div class="aps-col s12 m6 aps-row">
<div class="aps-col s6">
<div class="aps-panel">
<span class="shop-item-helper right delay-{{ delay }}">{{ lang('ASS_ITEM_PRICE') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content aps-center">
{% if S_SALE %}
<span class="aps-positive" title="{{ lang('ASS_ON_SALE') }}">{{ aps_display(SALE_PRICE) }}</span>
{% else %}
{{ aps_display(PRICE) }}
{% endif %}
</div>
</div>
</div>
<div class="aps-col s6">
<div class="aps-panel">
<span class="shop-item-helper left delay-{{ delay }}">{{ lang('ASS_ITEM_STOCK') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content aps-center" title="{{ lang(S_STOCK_UNLIMITED ? 'ASS_UNLIMITED_STOCK' : (STOCK ? 'ASS_STOCK' : 'ASS_STOCK_OUT')) }}">
{% if S_STOCK_UNLIMITED %}
<strong>&infin;</strong>
{% elseif STOCK %}
<strong class="shop-item-stock {{ STOCK ? 'icon-gold' : 'error' }}">{{ STOCK }}</strong>&thinsp;/{{ STOCK_INITIAL }}
{% endif %}
</div>
</div>
</div>
{% if not S_GIFT_ONLY %}
<div class="aps-col s{{ S_GIFT and S_CAN_GIFT ? 8 : 12 }}">
<a class="aps-button-{{ not S_OUT_OF_STOCK ? 'green shop-relative' : 'red shop-cursor-ban' }} aps-center shop-block shop-bold shop-button-active"{% if not S_OUT_OF_STOCK %} href="{{ U_PURCHASE }}" data-shop-link="shop_purchase"{% endif %}>
{% if not S_OUT_OF_STOCK %}
<span class="shop-item-helper right delay-{{ delay }}">{{ lang('ASS_ITEM_PURCHASE') }}</span>
{% set delay = delay + 1 %}
{% endif %}
{{ lang(S_OUT_OF_STOCK ? 'ASS_STOCK_OUT' : 'ASS_PURCHASE') }}
</a>
</div>
{% endif %}
{% if S_GIFT and S_CAN_GIFT %}
<div class="aps-col s{{ S_GIFT_ONLY ? 12 : 4 }}">
<a class="aps-button-{{ S_GIFT_ONLY and S_OUT_OF_STOCK ? 'red' : 'blue' }} aps-center shop-block shop-relative{{ S_GIFT_ONLY ? ' shop-bold shop-button-active' }}{{ not S_GIFT_ONLY and S_OUT_OF_STOCK ? ' shop-button-disabled' }}"{% if not S_OUT_OF_STOCK %} href="{{ U_GIFT }}" title="{{ lang('ASS_GIFT') }}" data-shop-link="shop_purchase"{% endif %}>
{% if not S_OUT_OF_STOCK %}
<span class="shop-item-helper left delay-{{ delay }}">{{ lang('ASS_ITEM_GIFT') }}</span>
{% set delay = delay + 1 %}
{% endif %}
<i class="icon {{ aps_config('ass_gift_icon') }} fa-fw" aria-hidden="true"></i>
<span{% if not S_GIFT_ONLY %} class="sr-only"{% endif %}>{{ lang('ASS_GIFT') }}</span>
</a>
</div>
{% endif %}
<div class="aps-col s12">
<div class="aps-panel shop-relative">
<span class="shop-item-helper left delay-{{ delay }}">{{ lang('ASS_ITEM_INFORMATION') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content">
<ul class="fa-ul shop-darken-span">
<li>
<i class="icon fa-hashtag fa-li"></i>
{% if COUNT %}
{{ lang('ASS_ITEM_USE_COUNT', COUNT) }}
{% else %}
{{ lang('ASS_ITEM_USE_UNLIMITED') }}
{% endif %}
</li>
<li>
<i class="icon fa-hourglass-start fa-li"></i>
{% if EXPIRE_WITHIN %}
{{ lang('ASS_ITEM_EXPIRE_WITHIN', EXPIRE_WITHIN) }}
{% else %}
{{ lang('ASS_ITEM_EXPIRE_NEVER') }}
{% endif %}
</li>
<li>
<i class="icon fa-undo fa-li"></i>
{% if REFUND_WITHIN %}
{{ lang('ASS_ITEM_REFUND_WITHIN', REFUND_WITHIN) }}
{% else %}
{{ lang('ASS_ITEM_REFUND_NEVER') }}
{% endif %}
</li>
</ul>
</div>
</div>
</div>
<div class="aps-col s12">
<div class="aps-row aps-panel">
<div class="aps-col s{{ EDIT_TIME ? 6 : 12 }} aps-no-mar-bot shop-relative" title="{{ lang('ASS_TIME_CREATED') }}">
<span class="shop-item-helper top-right delay-{{ delay }}">{{ lang('ASS_ITEM_CREATE_TIME') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content shop-padding">
<i class="icon fa-check-square-o fa-fw"></i>
{{ user.format_date(CREATE_TIME) }}
</div>
</div>
{% if EDIT_TIME %}
<div class="aps-col s6 aps-no-mar-bot shop-relative" title="{{ lang('ASS_TIME_EDITED') }}">
<span class="shop-item-helper top-left delay-{{ delay }}">{{ lang('ASS_ITEM_EDIT_TIME') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content shop-padding">
<i class="icon fa-pencil-square-o fa-fw"></i>
{{ user.format_date(EDIT_TIME) }}
</div>
</div>
{% endif %}
</div>
</div>
{% if S_SALE %}
<div class="aps-col s12 aps-center">
<em>{{ lang('ASS_SALE_END_ON', user.format_date(SALE_UNTIL_UNIX)) }}</em>
</div>
{% endif %}
{% if AVAILABLE_UNTIL_UNIX and S_AVAILABLE %}
<div class="aps-col s12 aps-center">
<em>{{ lang('ASS_AVAILABILITY_END_ON', user.format_date(AVAILABLE_UNTIL_UNIX)) }}</em>
</div>
{% endif %}
</div>
{% if DESC_HTML %}
<div class="aps-col s12">
<div class="aps-panel shop-relative">
<span class="shop-item-helper right delay-{{ delay }}">{{ lang('ASS_ITEM_DESCRIPTION') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-content content">
{{ DESC_HTML }}
</div>
</div>
</div>
{% endif %}
</div>
{% if IMAGES_SRC %}
<div class="aps-row">
<div class="aps-col s12 shop-fake-width">
<span class="shop-item-helper right delay-{{ delay }}">{{ lang('ASS_ITEM_IMAGES') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel">
<div class="aps-panel-content">
<div data-shop-carousel="images">
{% for image in IMAGES_SRC %}
<div>
<img class="shop-carousel-images" src="{{ image }}" alt="{{ TITLE }}" />
</div>
{% endfor %}
</div>
</div>
<div class="aps-panel-footer">
{% for image in IMAGES_SRC %}
<img class="shop-carousel-nav-img" src="{{ image }}" alt="{{ TITLE }}" />
{% endfor %}
</div>
</div>
</div>
</div>
{% endif %}
{% if ass_related|length %}
<div class="aps-row">
<div class="aps-col s12">
<div class="aps-panel shop-relative">
<span class="shop-item-helper left delay-{{ delay }}">{{ lang('ASS_RELATED_ITEMS') }}</span>
{% set delay = delay + 1 %}
<div class="aps-panel-header">
<h3>{{ lang('ASS_RELATED_ITEMS') }}</h3>
</div>
<div class="aps-panel-content">
<div class="aps-row">
{% for item in ass_related %}
<div class="aps-col s6 m3">
{{ include('@phpbbstudio_ass/ass_item_panel.html') }}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,37 @@
<div class="shop-relative shop-panel-height shop-padding {{ item.BACKGROUND_SRC ? 'shop-panel-background' : 'shop-vertical' }}" data-shop-item="{{ item.ID }}"{% if item.BACKGROUND_SRC %} style="background-image: url({{ item.BACKGROUND_SRC }})"{% endif %}>
{% if not item.BACKGROUND_SRC %}
<i class="icon {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-fw shop-text-indent-10 icon-xl icon-lightgray"></i>
{% endif %}
<div class="shop-panel-bottom aps-center">
{% if S_CAN_PURCHASE and not item.S_GIFT_ONLY %}
{% if item.S_OUT_OF_STOCK %}
<span class="aps-button-red shop-button-active pull-left" title="{{ lang('ASS_STOCK_OUT') }}">
<i class="icon {{ aps_config('ass_shop_icon') }} fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_PURCHASE') }}</span>
</span>
{% else %}
<a class="aps-button-green pull-left" href="{{ item.U_PURCHASE }}" title="{{ lang('ASS_PURCHASE') }}" data-shop-link="ass_purchase">
<i class="icon {{ aps_config('ass_shop_icon') }} fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_PURCHASE') }}</span>
</a>
{% endif %}
{% endif %}
{% if S_CAN_GIFT and item.S_GIFT %}
<a class="aps-button-blue pull-right" href="{{ item.U_GIFT }}" title="{{ lang('ASS_GIFT') }}" data-shop-link="ass_gift">
<i class="icon {{ aps_config('ass_gift_icon') }} fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_GIFT') }}</span>
</a>
{% endif %}
<a class="shop-text-large shop-panel-header-link" href="{{ item.U_VIEW }}" data-item-title="{{ item.TITLE }}">
{{ item.TITLE }}
</a>
{% if item.S_OUT_OF_STOCK %}
<span class="shop-block shop-text-med aps-negative" title="{{ lang('ASS_STOCK_OUT') }}">{{ aps_display(item.PRICE) }}</span>
{% elseif item.S_SALE %}
<span class="shop-block shop-text-med aps-positive" title="{{ lang('ASS_ON_SALE') }}">{{ aps_display(item.SALE_PRICE) }}</span>
{% else %}
<span class="shop-block shop-text-med shop-text-blue">{{ aps_display(item.PRICE) }}</span>
{% endif %}
</div>
</div>

View File

@@ -0,0 +1,185 @@
<div class="shop-inventory-item" data-shop-item="{{ item.ID }}">
{% if S_GIFT_ANIMATION %}
<div class="shop-inventory-gift shop-zoom-hide">
<div class="shop-inventory-gift-icon">
<i class="fa fa-gift"></i>
</div>
<span class="shop-stars shop-stars-top shop-zoom-out">
{% for i in 1..5 %}
<i class="fa fa-star"></i>
{% endfor %}
</span>
<span class="shop-stars shop-stars-bottom shop-zoom-out">
{% for i in 1..5 %}
<i class="fa fa-star"></i>
{% endfor %}
</span>
<svg class="shop-zoom-out" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 -1 400 402">
<path d="M 400 200 A 200 200 0 0 1 200 400 A 200 200 0 0 1 0 200 A 200 200 0 0 1 200 0 A 200 200 0 0 1 400 200 Z"></path>
<path d="M 219.566 206.068 M 200 395 C 92.303 395 5 307.697 5 200 C 5 92.303 92.303 5 200 5 C 307.697 5 395 92.303 395 200"></path>
<path d="M 250.689 383.163 C 234.552 387.619 217.554 390 200 390 C 95.066 390 10 304.934 10 200 C 10 95.066 95.066 10 200 10 C 304.934 10 390 95.066 390 200 C 390 210.848 389.091 221.483 387.345 231.834"></path>
<path d="M 385 200 C 385 302.173 302.173 385 200 385 C 97.827 385 15 302.173 15 200 C 15 97.827 97.827 15 200 15 C 302.173 15 385 97.827 385 200 Z"></path>
<path d="M 200 380 M 181.098 379.019 C 90.57 369.572 20 293.028 20 200 C 20 100.588 100.588 20 200 20 C 292.203 20 368.213 89.323 378.752 178.693"></path>
<path d="M 200 375 C 103.35 375 25 296.65 25 200 C 25 103.35 103.35 25 200 25 C 296.65 25 375 103.35 375 200"></path>
<path d="M 219.433 31.099 C 304.17 40.741 370 112.682 370 200 C 370 287.453 303.966 359.482 219.038 368.946 M 200 370 M 175.05 368.182 C 92.99 356.113 30 285.413 30 200 C 30 114.408 93.254 43.59 175.567 31.743"></path>
<path d="M 365 200 C 365 291.127 291.127 365 200 365 C 108.873 365 35 291.127 35 200 C 35 108.873 108.873 35 200 35 C 291.127 35 365 108.873 365 200 Z"></path>
</svg>
</div>
{% endif %}
<div class="aps-row{{ S_GIFT_ANIMATION ? ' shop-zoom-in' }}">
<div class="aps-col s1 shop-no-pad">
{% if item.U_STACK_PREV %}
<a class="aps-button-blue" href="{{ item.U_STACK_PREV }}" title="{{ lang('PREVIOUS') }}">
<i class="icon fa-chevron-left fa-fw"></i>
</a>
{% endif %}
</div>
<div class="aps-col s10 shop-no-pad">
<h2 class="aps-no-mar aps-center shop-padding shop-no-pad-bot shop-text-darkgray">{{ item.TITLE }}</h2>
</div>
<div class="aps-col s1 shop-no-pad">
{% if item.U_STACK_NEXT %}
<a class="aps-button-blue" href="{{ item.U_STACK_NEXT }}" title="{{ lang('NEXT') }}">
<i class="icon fa-chevron-right fa-fw"></i>
</a>
{% endif %}
</div>
{% if U_DOWNLOAD_FILE and S_LOADED_ITEM %}
<div class="aps-col s12 shop-no-pad">
<div class="aps-panel">
<div class="aps-panel-content shop-text-darkgray">
<script>
setTimeout(function() {
window.location = '{{ U_DOWNLOAD_FILE|e('js') }}';
}, 1500);
</script>
{{ lang('ASS_TYPE_FILE_START') }}
</div>
<div class="aps-panel-content">
{{ lang('ASS_TYPE_FILE_START_NOT') }}
</div>
<div class="aps-panel-footer aps-center">
<a class="aps-button-green shop-button-active" href="{{ U_DOWNLOAD_FILE }}">
<i class="icon fa-download fa-fw" aria-hidden="true"></i>
<span>{{ item.ACTIVATE }}</span>
</a>
</div>
</div>
</div>
{% endif %}
{% if item.S_TYPE_ERROR %}
<div class="aps-col s12 shop-no-pad">
<div class="aps-panel">
<div class="aps-panel-header error">
<i class="icon fa-exclamation-triangle icon-white shop-panel-icon shop-panel-icon-red"></i>
{{ lang('ERROR') }}
</div>
<div class="aps-panel-content shop-text-darkgray">
{{ lang('ASS_ITEM_TYPE_NOT_EXIST') }}
</div>
<div class="aps-panel-content">
{{ lang('ASS_ERROR_LOGGED') }}
</div>
</div>
</div>
{% endif %}
{% if item.S_LIMIT or item.S_HAS_EXPIRED or item.S_WILL_EXPIRE %}
<div class="aps-col s12 shop-no-pad">
<div class="aps-button-{{ item.S_LIMIT or item.S_HAS_EXPIRED ? 'red' : 'blue' }} shop-button-active shop-cursor-normal">
{{ lang(item.S_LIMIT ? 'ASS_ITEM_USE_REACHED' : (item.S_HAS_EXPIRED ? 'ASS_ITEM_EXPIRED' : 'ASS_ITEM_EXPIRE_SOON')) }}
</div>
</div>
{% endif %}
{% if item.S_GIFTED %}
<div class="aps-col s12 shop-no-pad">
<div class="aps-panel">
<i class="icon {{ aps_config('ass_gift_icon') }} icon-white shop-panel-icon shop-panel-icon-small shop-panel-icon-blue"></i>
<div class="aps-panel-content">
{{ lang('ASS_GIFTED_BY', item.GIFTER_NAME) }}
</div>
</div>
</div>
{% endif %}
<div class="aps-col s3 shop-no-pad-left shop-inventory-item-img">
<div class="aps-panel">
<div class="aps-panel-content shop-no-pad {{ item.BACKGROUND_SRC ? 'shop-panel-background' : 'shop-vertical' }}"{% if item.BACKGROUND_SRC %} style="background-image: url({{ item.BACKGROUND_SRC }})"{% endif %}>
{% if not item.BACKGROUND_SRC %}
<i class="icon {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-fw shop-text-indent-10 icon-xl icon-lightgray"></i>
{% endif %}
</div>
</div>
</div>
<div class="aps-col s9 shop-no-pad-left shop-no-pad-right">
<div class="aps-panel">
<div class="aps-panel-content">
<ul class="fa-ul">
<li title="{{ lang('ASS_USAGES') }}">
<i class="icon fa-li fa-hashtag" aria-hidden="true"></i>
<span><strong class="shop-text-darkgray shop-inventory-item-count">{{ item.USE_COUNT }}</strong>&thinsp;/{{ item.COUNT ?: '&infin;' }}</span>
</li>
<li{% if not item.USE_UNIX %} class="hidden"{% endif %} title="{{ lang('ASS_USED_LAST') }}">
<i class="icon fa-li fa-clock-o" aria-hidden="true"></i>
<span class="shop-inventory-item-time">{{ user.format_date(item.USE_UNIX) }}</span>
</li>
<li title="{{ lang('ASS_EXPIRATION_DATE') }}">
<i class="icon fa-li fa-hourglass-end" aria-hidden="true"></i>
<span>{{ item.EXPIRE_SECONDS ? user.format_date(item.PURCHASE_UNIX + item.EXPIRE_SECONDS) : lang('NEVER') }}</span>
</li>
<li title="{{ lang('ASS_REFUND_BEFORE') }}">
<i class="icon fa-li fa-undo" aria-hidden="true"></i>
<span>{{ item.REFUND_SECONDS ? user.format_date(item.PURCHASE_UNIX + item.REFUND_SECONDS) : lang('NEVER') }}</span>
</li>
<li title="{{ lang(item.S_GIFTED ? 'ASS_GIFT_TIME' : 'ASS_PURCHASE_TIME') }}">
<i class="icon fa-li {{ aps_config(item.S_GIFTED ? 'ass_gift_icon' : 'ass_shop_icon') }}" aria-hidden="true"></i>
<span>{{ user.format_date(item.PURCHASE_UNIX) }}</span>
</li>
</ul>
</div>
</div>
</div>
<div class="aps-col s8 shop-no-pad-left">
{% if not item.S_HAS_EXPIRED and not item.S_LIMIT and not item.S_TYPE_ERROR %}
<a class="aps-button-green aps-center shop-block{{ not S_LOADED_ITEM or not U_DOWNLOAD_FILE ? ' shop-button-active' }}" href="{{ item.U_ACTIVATE }}" title="{{ item.ACTIVATE }}"{% if item.S_AJAX %} data-shop-link="{{ item.S_AJAX }}"{% endif %}>
{{ item.ACTIVATE }}
</a>
{% endif %}
</div>
{% if item.S_REFUND %}
<div class="aps-col s2 shop-no-pad shop-inventory-refund">
<a class="aps-button-blue aps-center shop-block" href="{{ item.U_REFUND }}" title="{{ lang('ASS_REFUND') }}" data-shop-link="shop_inventory_delete">
<i class="icon fa-undo fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_REFUND') }}</span>
</a>
</div>
{% endif %}
<div class="aps-col s{{ item.S_REFUND ? 2 : 4 }} shop-no-pad-right">
<a class="aps-button-red aps-center shop-block" href="{{ item.U_DELETE }}" title="{{ lang('ASS_DELETE') }}" data-shop-link="shop_inventory_delete">
<i class="icon fa-trash fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_DELETE') }}</span>
</a>
</div>
{% if item.DESC_HTML %}
<div class="aps-col s12 shop-no-pad">
<div class="aps-panel">
<div class="aps-panel-content content">
{{ item.DESC_HTML }}
</div>
</div>
</div>
{% endif %}
</div>
</div>

View File

@@ -0,0 +1,47 @@
<div class="aps-panel" data-shop-item="{{ item.ID }}">
<div class="aps-panel-header">
{% if ITEM_PANEL_ICON %}
<i class="icon shop-panel-icon{{ ITEM_PANEL_ICON }}"></i>
{% elseif item.S_FEATURED and item.S_SALE and SHOP_PANEL_FEATURED_SALE_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_FEATURED_SALE_ICON }}"></i>
{% elseif item.S_FEATURED and SHOP_PANEL_FEATURED_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_FEATURED_ICON }}" title="{{ lang('ASS_FEATURED') }}"></i>
{% elseif item.S_SALE and SHOP_PANEL_SALE_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_SALE_ICON }}" title="{{ lang('ASS_ON_SALE') }}"></i>
{% endif %}
<h3 class="shop-block"><a class="shop-text-darkgray shop-block shop-panel-header-link" href="{{ item.U_VIEW }}" data-item-title="{{ item.TITLE }}">{{ item.TITLE }}</a></h3>
</div>
<div class="aps-panel-content shop-panel-height {{ item.BACKGROUND_SRC ? 'shop-panel-background' : 'shop-vertical' }}"{% if item.BACKGROUND_SRC %} style="background-image: url({{ item.BACKGROUND_SRC }})"{% endif %}>
{% if not item.BACKGROUND_SRC %}
<i class="icon {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-fw shop-text-indent-10 icon-xl icon-lightgray"></i>
{% endif %}
</div>
<div class="aps-row aps-panel-footer">
<div class="aps-col s6 aps-no-mar-bot shop-no-pad">
{% if S_CAN_PURCHASE and not item.S_OUT_OF_STOCK and not item.S_GIFT_ONLY %}
<a class="aps-button-green shop-panel-footer-button" href="{{ item.U_PURCHASE }}" title="{{ lang('ASS_PURCHASE') }}" data-shop-link="ass_purchase">
<i class="icon {{ aps_config('ass_shop_icon') }} fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_PURCHASE') }}</span>
</a>
{% elseif item.S_GIFT and S_CAN_GIFT %}
<a class="aps-button-blue shop-panel-footer-button" href="{{ item.U_GIFT }}" title="{{ lang('ASS_GIFT') }}" data-shop-link="ass_gift">
<i class="icon {{ aps_config('ass_gift_icon') }} fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ASS_GIFT') }}</span>
</a>
{% elseif not item.S_STOCK_UNLIMITED %}
<strong class="shop-item-stock {{ item.STOCK ? 'icon-gold' : 'error' }}" title="{{ lang(item.STOCK ? 'ASS_STOCK' : 'ASS_STOCK_OUT') }}">{{ item.STOCK }}</strong>&thinsp;/{{ item.STOCK_INITIAL }}
{% elseif item.ICON %}
<i class="icon {{ item.ICON }} fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ item.TITLE }}</span>
{% endif %}
</div>
<div class="aps-col s6 aps-no-mar-bot shop-no-pad shop-text-right">
{% if item.S_SALE %}
<span class="aps-positive" title="{{ lang('ASS_ON_SALE') }}">{{ aps_display(item.SALE_PRICE) }}</span>
{% else %}
{{ aps_display(item.PRICE) }}
{% endif %}
</div>
</div>
</div>

View File

@@ -0,0 +1 @@
<p>{{ MESSAGE_TEXT }}</p>

View File

@@ -0,0 +1,45 @@
<nav>
{# Pagination's aria-labels should NOT be translated! #}
<ul class="shop-pagination aps-center" aria-label="pagination">
{% for item in shop_pagination %}
{% if item.S_IS_PREV or (not item.S_IS_PREV and loop.first) %}
<li>
<a class="aps-button-blue shop-block{{ not item.S_IS_PREV ? ' shop-button-disabled' }}"{% if item.S_IS_PREV %} href="{{ U_SHOP_PAGINATION_PREVIOUS_PAGE }}"{% endif %} aria-label="Previous page" role="button">
<i class="icon fa-chevron-left fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('PREVIOUS') }}</span>
</a>
</li>
{% endif %}
{% if item.S_IS_ELLIPSIS %}
<li>
<span class="aps-button-blue shop-block shop-button-disabled" role="separator">
<i class="icon fa-ellipsis-h fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('ELLIPSIS') }}</span>
</span>
</li>
{% elseif item.S_IS_CURRENT %}
<li>
<a class="aps-button-blue shop-block shop-button-active" href="{{ item.PAGE_URL }}" aria-label="Page {{ item.PAGE_NUMBER }}, Current page" aria-current="true" role="button">
{{ item.PAGE_NUMBER }}
</a>
</li>
{% elseif not item.S_IS_PREV and not item.S_IS_NEXT %}
<li>
<a class="aps-button-blue shop-block" href="{{ item.PAGE_URL }}" aria-label="Page {{ item.PAGE_NUMBER }}" aria-current="true" role="button">
{{ item.PAGE_NUMBER }}
</a>
</li>
{% endif %}
{% if item.S_IS_NEXT or (not item.S_IS_NEXT and loop.last) %}
<li>
<a class="aps-button-blue shop-block{{ not item.S_IS_NEXT ? ' shop-button-disabled' }}"{% if item.S_IS_NEXT %} href="{{ U_SHOP_PAGINATION_NEXT_PAGE }}"{% endif %} aria-label="Next page" role="button">
<i class="icon fa-chevron-right fa-fw" aria-hidden="true"></i>
<span class="sr-only">{{ lang('NEXT') }}</span>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</nav>

View File

@@ -0,0 +1,191 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block includes %}
{% INCLUDECSS '@phpbbstudio_ass/ass_common.css' %}
{% endblock %}
{% block nav %}
{% for category in ass_shop_categories %}
<li>
<a class="aps-list-item{{ category.S_SELECTED ? ' aps-list-active' }}" href="{{ category.U_VIEW }}" title="{{ category.TITLE }}">
{% if category.ICON %}<i class="icon {{ category.ICON }} fa-fw" aria-hidden="true"></i>{% endif %}
<span class="sr-only">{{ category.TITLE }}</span>
</a>
</li>
{% endfor %}
{% endblock %}
{% block main %}
<div class="aps-row">
{% if ICON %}
<div class="aps-col s2">
<div class="aps-panel aps-center">
<div class="aps-panel-content">
<i class="fa {{ ICON }} fa-fw fa-3x icon-aps-blue" aria-hidden="true"></i>
</div>
</div>
</div>
{% endif %}
<div class="aps-col s{{ ICON ? 10 : 12 }}">
<div class="shop-title">
<h1 class="aps-no-mar shop-text-darkgray">{{ TITLE }}</h1>
</div>
</div>
<div class="aps-col s12 m6">
<div class="aps-panel">
<div class="aps-panel-content aps-center shop-panel-height {{ BACKGROUND_SRC ? 'shop-panel-background' : 'shop-vertical' }}"{% if BACKGROUND_SRC %} style="background-image: url({{ BACKGROUND_SRC }})"{% endif %}>
{% if S_FEATURED and S_SALE and SHOP_PANEL_FEATURED_SALE_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_FEATURED_SALE_ICON }}"></i>
{% elseif S_FEATURED and SHOP_PANEL_FEATURED_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_FEATURED_ICON }}" title="{{ lang('ASS_FEATURED') }}"></i>
{% elseif S_SALE and SHOP_PANEL_SALE_ICON %}
<i class="icon shop-panel-icon{{ SHOP_PANEL_SALE_ICON }}" title="{{ lang('ASS_ON_SALE') }}"></i>
{% endif %}
{% if not BACKGROUND_SRC %}
<i class="icon {{ aps_config('ass_no_image_icon') }} fa-fw shop-text-indent-10 icon-xl icon-lightgray"></i>
{% endif %}
</div>
</div>
</div>
<div class="aps-col s12 m6 aps-row">
{% if S_CONFIRM_ACTION %}
<div class="aps-col s6">
<div class="aps-panel">
<div class="aps-panel-content aps-center">
{% if S_SALE %}
<span class="aps-positive" title="{{ lang('ASS_ON_SALE') }}">{{ aps_display(ASS_PURCHASE_PRICE) }}</span>
{% else %}
{{ aps_display(ASS_PURCHASE_PRICE) }}
{% endif %}
</div>
</div>
</div>
<div class="aps-col s6">
<div class="aps-panel">
<div class="aps-panel-content aps-center" title="{{ lang(S_STOCK_UNLIMITED ? 'ASS_UNLIMITED_STOCK' : (STOCK ? 'ASS_STOCK' : 'ASS_STOCK_OUT')) }}">
{% if S_STOCK_UNLIMITED %}
<strong>&infin;</strong>
{% elseif STOCK %}
<strong class="{{ STOCK ? 'icon-gold' : 'error' }}">{{ STOCK }}</strong>&thinsp;/{{ STOCK_INITIAL }}
{% endif %}
</div>
</div>
</div>
{% endif %}
<div class="aps-col s12">
<div class="aps-panel">
<div class="aps-panel-content">
<ul class="fa-ul shop-darken-span">
<li>
<i class="icon fa-hashtag fa-li"></i>
{% if COUNT %}
{{ lang('ASS_ITEM_USE_COUNT', COUNT) }}
{% else %}
{{ lang('ASS_ITEM_USE_UNLIMITED') }}
{% endif %}
</li>
<li>
<i class="icon fa-hourglass-start fa-li"></i>
{% if EXPIRE_WITHIN %}
{{ lang('ASS_ITEM_EXPIRE_WITHIN', EXPIRE_WITHIN) }}
{% else %}
{{ lang('ASS_ITEM_EXPIRE_NEVER') }}
{% endif %}
</li>
<li>
<i class="icon fa-undo fa-li"></i>
{% if REFUND_WITHIN %}
{{ lang('ASS_ITEM_REFUND_WITHIN', REFUND_WITHIN) }}
{% else %}
{{ lang('ASS_ITEM_REFUND_NEVER') }}
{% endif %}
</li>
</ul>
</div>
</div>
</div>
{% if S_CONFIRM_ACTION %}
<div class="aps-col s12">
<form class="aps-form" id="confirm" action="{{ S_CONFIRM_ACTION }}" method="post">
<div class="aps-panel">
<div class="aps-panel-header">
<h3>{{ MESSAGE_TITLE }}</h3>
</div>
{% if not S_ASS_PURCHASE %}
<div class="aps-panel-content">
<label class="shop-block shop-mar-bot" for="username">{{ lang('ASS_GIFT_USER') }}</label>
<input id="username" name="username" type="text" placeholder="{{ lang('USERNAME') }}">
</div>
{% endif %}
<div class="aps-panel-content">
{{ MESSAGE_TEXT }}
</div>
<div class="aps-panel-footer aps-center">
{{ S_HIDDEN_FIELDS }}
<input class="aps-button-green" type="submit" name="confirm" value="{{ lang('YES') }}" />&nbsp;
<a class="aps-button-red" href="{{ path('phpbbstudio_ass_shop') }}">{{ lang('NO') }}</a>
</div>
</div>
</form>
</div>
{% else %}
<div class="aps-col s12">
<div class="aps-panel">
<div class="aps-panel-header">
<h3>{{ lang(S_ASS_PURCHASE ? 'ASS_PURCHASE' : 'ASS_GIFT') }}</h3>
</div>
<div class="aps-panel-content">
<p>
{% if S_ASS_PURCHASE %}
<span class="shop-text-darkgray shop-block">{{ lang('ASS_PURCHASE_SUCCESS') }}</span>
{{ lang('ASS_INVENTORY_ADDED') }}
{% else %}
<span class="shop-text-darkgray shop-block">{{ lang('ASS_GIFT_SUCCESS') }}</span>
{{ lang('ASS_INVENTORY_ADDED_USER', RECIPIENT_NAME) }}
{% endif %}
</p>
<p>
<span class="shop-block">
{{ lang('ASS_POINTS_DEDUCTED') ~ lang('COLON') }}
{{ aps_display(ASS_PURCHASE_PRICE) }}
</span>
<span class="shop-block">
{{ lang('ASS_POINTS_BALANCE', aps_name()) ~ lang('COLON') }}
{{ aps_display(NEW_USER_POINTS) }}
</span>
</p>
{% if EXPIRE_UNIX %}
<p>
<span class="shop-block">{{ lang('ASS_ITEM_USE_BEFORE') }}</span>
{{ user.format_date(EXPIRE_UNIX) }}
</p>
{% endif %}
<p>
{% if S_ASS_PURCHASE %}
<a class="aps-button-blue" href="{{ U_INVENTORY }}">{{ lang('ASS_INVENTORY_GO') }}</a>
{% else %}
<a class="aps-button-blue" href="{{ path('phpbbstudio_ass_shop') }}">{{ lang('ASS_SHOP_INDEX') }}</a>
{% if U_SEND_PM %}
<a class="aps-button-green" href="{{ U_SEND_PM }}">{{ lang('SEND_PRIVATE_MESSAGE') }}</a>
{% endif %}
{% endif %}
</p>
</div>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,144 @@
<div class="aps-main">
<div class="aps-body">
<div class="aps-row">
<div class="aps-col s12">
<div class="shop-title">
<h1 class="aps-no-mar shop-text-darkgray">{{ TITLE }}</h1>
</div>
</div>
{% if not S_PURCHASE_SUCCESS %}
<div class="aps-col s6">
<div class="aps-panel">
<div class="aps-panel-content aps-center">
{% if S_SALE %}
<span class="aps-positive" title="{{ lang('ASS_ON_SALE') }}">{{ aps_display(ASS_PURCHASE_PRICE) }}</span>
{% else %}
{{ aps_display(ASS_PURCHASE_PRICE) }}
{% endif %}
</div>
</div>
</div>
<div class="aps-col s6">
<div class="aps-panel">
<div class="aps-panel-content aps-center" title="{{ lang(S_STOCK_UNLIMITED ? 'ASS_UNLIMITED_STOCK' : (STOCK ? 'ASS_STOCK' : 'ASS_STOCK_OUT')) }}">
{% if S_STOCK_UNLIMITED %}
<strong>&infin;</strong>
{% elseif STOCK %}
<strong class="{{ STOCK ? 'icon-gold' : 'error' }}">{{ STOCK }}</strong>&thinsp;/{{ STOCK_INITIAL }}
{% endif %}
</div>
</div>
</div>
{% endif %}
<div class="aps-col s12">
<div class="aps-panel">
<div class="aps-panel-content">
<ul class="fa-ul shop-darken-span shop-text-left">
<li>
<i class="icon fa-hashtag fa-li"></i>
{% if COUNT %}
{{ lang('ASS_ITEM_USE_COUNT', COUNT) }}
{% else %}
{{ lang('ASS_ITEM_USE_UNLIMITED') }}
{% endif %}
</li>
<li>
<i class="icon fa-hourglass-start fa-li"></i>
{% if EXPIRE_WITHIN %}
{{ lang('ASS_ITEM_EXPIRE_WITHIN', EXPIRE_WITHIN) }}
{% else %}
{{ lang('ASS_ITEM_EXPIRE_NEVER') }}
{% endif %}
</li>
<li>
<i class="icon fa-undo fa-li"></i>
{% if REFUND_WITHIN %}
{{ lang('ASS_ITEM_REFUND_WITHIN', REFUND_WITHIN) }}
{% else %}
{{ lang('ASS_ITEM_REFUND_NEVER') }}
{% endif %}
</li>
</ul>
</div>
</div>
</div>
{% if not S_PURCHASE_SUCCESS and not S_ASS_PURCHASE %}
<div class="aps-col s12">
<div class="aps-panel">
<div class="aps-panel-content">
<form class="aps-form">
<label class="shop-block shop-mar-bot" for="username">{{ lang('ASS_GIFT_USER') }}</label>
<input id="username" name="username" type="text" placeholder="{{ lang('USERNAME') }}">
</form>
</div>
</div>
</div>
{% endif %}
{% if S_ASS_PURCHASE and not S_PURCHASE_SUCCESS %}
<div class="aps-col s12">
<div class="aps-panel">
<div class="aps-panel-content">
{% if ASS_ITEM_STACK %}
{{ lang('ASS_WARNING_STACK', ASS_ITEM_STACK) }}
{% else %}
{{ lang('ASS_ERROR_NOT_OWNED') }}
{% endif %}
</div>
</div>
</div>
{% endif %}
<div class="aps-col s12">
<div class="aps-panel">
<div class="aps-panel-content">
{% if not S_PURCHASE_SUCCESS %}
{{ MESSAGE_TEXT }}
{% else %}
<p>
{% if S_ASS_PURCHASE %}
<span class="shop-text-darkgray shop-block">{{ lang('ASS_PURCHASE_SUCCESS') }}</span>
{{ lang('ASS_INVENTORY_ADDED') }}
{% else %}
<span class="shop-text-darkgray shop-block">{{ lang('ASS_GIFT_SUCCESS') }}</span>
{{ lang('ASS_INVENTORY_ADDED_USER', RECIPIENT_NAME) }}
{% endif %}
</p>
<p>
<span class="shop-block">
{{ lang('ASS_POINTS_DEDUCTED') ~ lang('COLON') }}
{{ aps_display(ASS_PURCHASE_PRICE) }}
</span>
<span class="shop-block">
{{ lang('ASS_POINTS_BALANCE', aps_name()) ~ lang('COLON') }}
{{ aps_display(NEW_USER_POINTS) }}
</span>
</p>
{% if EXPIRE_UNIX %}
<p>
<span class="shop-block">{{ lang('ASS_ITEM_USE_BEFORE') }}</span>
{{ user.format_date(EXPIRE_UNIX) }}
</p>
{% endif %}
<p>
{% if S_ASS_PURCHASE %}
<a class="aps-button-blue" href="{{ U_INVENTORY }}">{{ lang('ASS_INVENTORY_GO') }}</a>
{% else %}
<a class="aps-button-blue" href="{{ path('phpbbstudio_ass_shop') }}">{{ lang('ASS_SHOP_INDEX') }}</a>
{% if U_SEND_PM %}
<a class="aps-button-green" href="{{ U_SEND_PM }}">{{ lang('SEND_PRIVATE_MESSAGE') }}</a>
{% endif %}
{% endif %}
</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,64 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block includes %}
{% INCLUDEJS '@phpbbstudio_ass/js/slick.min.js' %}
{% INCLUDECSS '@phpbbstudio_ass/slick.css' %}
{% INCLUDEJS '@phpbbstudio_ass/js/ass_common.js' %}
{% INCLUDECSS '@phpbbstudio_ass/ass_common.css' %}
{% endblock %}
{% block nav %}
{% for category in ass_shop_categories %}
<li>
<a class="aps-list-item{{ category.S_SELECTED ? ' aps-list-active' }}" href="{{ category.U_VIEW }}" title="{{ category.TITLE }}">
{% if category.ICON %}<i class="icon {{ category.ICON }} fa-fw" aria-hidden="true"></i>{% endif %}
<span class="sr-only">{{ category.TITLE }}</span>
</a>
</li>
{% endfor %}
{% endblock %}
{% block main %}
{{ include('@phpbbstudio_ass/ass_carousel.html') }}
<div class="aps-row">
{% for panel, data in ass_panels %}
{% if attribute(loops, 'ass_' ~ panel) is defined %}
{% set items = attribute(loops, 'ass_' ~ panel) %}
{% if data.carousel %}
<div class="aps-col s12 m6 shop-fake-width">
<div class="aps-panel">
<div class="aps-panel-header">
{% set icon = attribute(_context, 'SHOP_PANEL_' ~ panel|upper ~ '_ICON') %}
{% if icon %}
<i class="icon shop-panel-icon{{ icon }}"></i>
{% endif %}
<h3>{{ lang(data.title) }}</h3>
</div>
<div class="aps-panel-content shop-overflow shop-no-pad">
<div data-shop-carousel="true">
{% for item in items %}
{{ include('@phpbbstudio_ass/ass_item_carousel.html') }}
{% else %}
<div class="aps-center shop-vertical shop-padding shop-panel-height">
<strong class="error">{{ lang('ASS_ITEMS_NONE') }}</strong>
</div>
{% endfor %}
</div>
</div>
<div class="aps-panel-footer shop-carousel-footer"></div>
</div>
</div>
{% else %}
{% for item in items %}
<div class="aps-col s6 m{{ aps_config('ass_panel_' ~ panel ~ '_width') }}">
{{ include('@phpbbstudio_ass/ass_item_panel.html', { ITEM_PANEL_ICON: attribute(_context, 'SHOP_PANEL_' ~ panel|upper ~ '_ICON') }) }}
</div>
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,27 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
{% if available|length %}
<div class="aps-collection">
{% for item in available %}
<div class="aps-collection-item aps-avatar">
{% if item.BACKGROUND_SRC %}
<img class="avatar" src="{{ item.BACKGROUND_SRC }}" alt="{{ item.TITLE }}" />
{% else %}
<i class="avatar fa {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-3x icon-gray" aria-hidden="true"></i>
{% endif %}
<span class="title">{{ item.TITLE }}</span><br />
<em>
<i class="icon calender-times-o fa-fw" aria-hidden="true"></i>
{{ user.format_date(item.AVAILABLE_UNTIL_UNIX) }}
</em>
<a class="aps-secondary-content" href="{{ item.U_VIEW }}">
<i class="icon fa-external-link fa-fw"></i>
</a>
</div>
{% endfor %}
</div>
{% else %}
<div class="error aps-center">{{ lang('ASS_ITEMS_NONE') }}</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,13 @@
{% block width %}s12 m4{% endblock %}
{% block content %}
<div class="aps-collection">
{% for user in buyers %}
<div class="aps-collection-item aps-avatar">
{{ user.AVATAR ? user.AVATAR }}
<span class="title">{{ user.NAME }}</span>
<p>{{ user.COUNT }}</p>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,18 @@
{% block width %}s12 m6 aps-js{% endblock %}
{% block content %}
<canvas data-aps-chart="pie"
data-aps-time="{{ aps_config('aps_display_graph_time') }}"
data-aps-empty="{{ lang('APS_POINTS_DATA_EMPTY', aps_name()) }}"
aria-label="{{ lang('APS_POINTS_PER_FORUM', aps_name()) }}"
role="img">
<p>{{ lang('APS_POINTS_PER_FORUM', aps_name()) }}</p>
</canvas>
<div class="hidden">
{% for forum in aps_forums %}
<div data-aps-labels="{{ forum.NAME|e }}"
data-aps-value="{{ aps_format(forum.POINTS) }}">
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,27 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
{% if featured|length %}
<div class="aps-collection">
{% for item in featured %}
<div class="aps-collection-item aps-avatar">
{% if item.BACKGROUND_SRC %}
<img class="avatar" src="{{ item.BACKGROUND_SRC }}" alt="{{ item.TITLE }}" />
{% else %}
<i class="avatar fa {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-3x icon-gray" aria-hidden="true"></i>
{% endif %}
<span class="title">{{ item.TITLE }}</span><br />
<em>
<i class="icon {{ aps_config('ass_panel_featured_icon') ?: 'calender-times-o' }} fa-fw" aria-hidden="true"></i>
{{ user.format_date(item.FEATURED_UNTIL_UNIX) }}
</em>
<a class="aps-secondary-content" href="{{ item.U_VIEW }}">
<i class="icon fa-external-link fa-fw"></i>
</a>
</div>
{% endfor %}
</div>
{% else %}
<div class="error aps-center">{{ lang('ASS_ITEMS_NONE') }}</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,13 @@
{% block width %}s12 m4{% endblock %}
{% block content %}
<div class="aps-collection">
{% for user in gifters %}
<div class="aps-collection-item aps-avatar">
{{ user.AVATAR ? user.AVATAR }}
<span class="title">{{ user.NAME }}</span>
<p>{{ user.COUNT }}</p>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,23 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
{% if limited|length %}
<div class="aps-collection">
{% for item in limited %}
<div class="aps-collection-item aps-avatar">
{% if item.BACKGROUND_SRC %}
<img class="avatar" src="{{ item.BACKGROUND_SRC }}" alt="{{ item.TITLE }}" />
{% else %}
<i class="avatar fa {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-3x icon-gray" aria-hidden="true"></i>
{% endif %}
<span class="title">{{ item.TITLE }}</span>
<a class="aps-secondary-content" href="{{ item.U_VIEW }}">
{{ item.STOCK }}
</a>
</div>
{% endfor %}
</div>
{% else %}
<div class="error aps-center">{{ lang('ASS_ITEMS_NONE') }}</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,23 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
{% if purchases|length %}
<div class="aps-collection">
{% for item in purchases %}
<div class="aps-collection-item aps-avatar">
{% if item.BACKGROUND_SRC %}
<img class="avatar" src="{{ item.BACKGROUND_SRC }}" alt="{{ item.TITLE }}" />
{% else %}
<i class="avatar fa {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-3x icon-gray" aria-hidden="true"></i>
{% endif %}
<span class="title">{{ item.TITLE }}</span><br />
<a class="aps-secondary-content" href="{{ item.U_VIEW }}">
{{ item.PURCHASES }}
</a>
</div>
{% endfor %}
</div>
{% else %}
<div class="error aps-center">{{ lang('ASS_ITEMS_NONE') }}</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,18 @@
{% block width %}s12 m6 aps-js{% endblock %}
{% block content %}
<canvas data-aps-chart="pie"
data-aps-time="{{ aps_config('aps_display_graph_time') }}"
data-aps-empty="{{ lang('APS_POINTS_DATA_EMPTY', aps_name()) }}"
aria-label="{{ lang('ASS_PURCHASES_PER_GROUP', aps_name()) }}"
role="img">
<p>{{ lang('APS_PURCHASES_PER_GROUP', aps_name()) }}</p>
</canvas>
<div class="hidden">
{% for category in purchases_category %}
<div data-aps-labels="{{ category.NAME|e }}"
data-aps-value="{{ category.PURCHASES }}">
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,18 @@
{% block width %}s12 m6 aps-js{% endblock %}
{% block content %}
<canvas data-aps-chart="pie"
data-aps-time="{{ aps_config('aps_display_graph_time') }}"
data-aps-empty="{{ lang('APS_POINTS_DATA_EMPTY', aps_name()) }}"
aria-label="{{ lang('ASS_PURCHASES_PER_GROUP', aps_name()) }}"
role="img">
<p>{{ lang('APS_PURCHASES_PER_GROUP', aps_name()) }}</p>
</canvas>
<div class="hidden">
{% for group in purchases_group %}
<div data-aps-labels="{{ group.NAME|e }}"
data-aps-value="{{ group.PURCHASES }}">
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,27 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
{% if recent|length %}
<div class="aps-collection">
{% for item in recent %}
<div class="aps-collection-item aps-avatar">
{% if item.BACKGROUND_SRC %}
<img class="avatar" src="{{ item.BACKGROUND_SRC }}" alt="{{ item.TITLE }}" />
{% else %}
<i class="avatar fa {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-3x icon-gray" aria-hidden="true"></i>
{% endif %}
<span class="title">{{ item.TITLE }}</span><br />
<em>
<i class="icon fa-pencil-square-o fa-fw" aria-hidden="true"></i>
{{ user.format_date(item.CREATE_TIME) }}
</em>
<a class="aps-secondary-content" href="{{ item.U_VIEW }}">
<i class="icon fa-external-link fa-fw"></i>
</a>
</div>
{% endfor %}
</div>
{% else %}
<div class="error aps-center">{{ lang('ASS_ITEMS_NONE') }}</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,27 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
{% if sale|length %}
<div class="aps-collection">
{% for item in sale %}
<div class="aps-collection-item aps-avatar">
{% if item.BACKGROUND_SRC %}
<img class="avatar" src="{{ item.BACKGROUND_SRC }}" alt="{{ item.TITLE }}" />
{% else %}
<i class="avatar fa {{ item.ICON ?: aps_config('ass_no_image_icon') }} fa-3x icon-gray" aria-hidden="true"></i>
{% endif %}
<span class="title">{{ item.TITLE }}</span><br />
<em>
<i class="icon {{ aps_config('ass_panel_sale_icon') ?: 'calender-times-o' }} fa-fw" aria-hidden="true"></i>
{{ user.format_date(item.SALE_UNTIL_UNIX) }}
</em>
<a class="aps-secondary-content" href="{{ item.U_VIEW }}">
<i class="icon fa-external-link fa-fw"></i>
</a>
</div>
{% endfor %}
</div>
{% else %}
<div class="error aps-center">{{ lang('ASS_ITEMS_NONE') }}</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,13 @@
{% block width %}s12 m4{% endblock %}
{% block content %}
<div class="aps-collection">
{% for user in spenders %}
<div class="aps-collection-item aps-avatar">
{{ user.AVATAR ? user.AVATAR }}
<span class="title">{{ user.NAME }}</span>
<p>{{ aps_display(user.COUNT) }}</p>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_NAVBAR_HEADER_PROFILE_LIST_AFTER %}
<li>
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_NAVBAR_HEADER_PROFILE_LIST_BEFORE %}
<li>
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_NAVBAR_HEADER_QUICK_LINKS_AFTER %}
<li>
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_NAVBAR_HEADER_QUICK_LINKS_BEFORE %}
<li>
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_NAVBAR_HEADER_USER_PROFILE_APPEND %}
<li class="rightside">
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_NAVBAR_HEADER_USER_PROFILE_PREPEND %}
<li class="rightside">
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,5 @@
{% if S_ASS_SHOP %}
<div class="studio-spinner" id="studio_spinner">
{% for i in 1..8 %}<span></span>{% endfor %}
</div>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_OVERALL_FOOTER_BREADCRUMB_APPEND %}
<li>
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_OVERALL_FOOTER_TEAMLINK_AFTER %}
<li class="rightside">
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_OVERALL_FOOTER_TEAMLINK_BEFORE %}
<li class="rightside">
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_OVERALL_FOOTER_TIMEZONE_AFTER %}
<li class="rightside">
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_OVERALL_FOOTER_TIMEZONE_BEFORE %}
<li class="rightside">
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_OVERALL_HEADER_NAVIGATION_APPEND %}
<li>
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_ASS_ENABLED and S_ASS_OVERALL_HEADER_NAVIGATION_PREPEND %}
<li>
<a href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}" role="menuitem">
<i class="icon {{ ASS_SHOP_ICON }} fa-fw" aria-hidden="true"></i><span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,16 @@
{% if S_ASS_ENABLED %}
<li>
<a class="aps-list-item{{ S_ASS_SHOP ? ' aps-list-active' }}" href="{{ path('phpbbstudio_ass_shop') }}" title="{{ lang('ASS_SHOP') }}">
<i class="icon {{ aps_config('ass_shop_icon') }} fa-fw"></i>
<span>{{ lang('ASS_SHOP') }}</span>
</a>
</li>
{% if S_REGISTERED_USER %}
<li>
<a class="aps-list-item{{ S_ASS_INVENTORY ? ' aps-list-active' }}" href="{{ path('phpbbstudio_ass_inventory') }}" title="{{ lang('ASS_INVENTORY') }}">
<i class="icon {{ aps_config('ass_inventory_icon') }} fa-fw"></i>
<span>{{ lang('ASS_INVENTORY') }}</span>
</a>
</li>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,640 @@
jQuery(function($) {
let studio = {
body: '.aps-body',
link: '[data-shop-link]',
ajax: {
alert: $('#phpbb_alert'),
data: $('#darkenwrapper'),
spinner: $('#studio_spinner'),
timer: null
},
carousel: {
items: $('[data-shop-carousel]'),
item: $('[data-shop-carousel-data]'),
data: {
dotsClass: 'shop-carousel-dots',
nextArrow: '<button class="aps-button-blue shop-carousel-next" type="button"><i class="icon fa-chevron-right fa-fw"></i></button>',
prevArrow: '<button class="aps-button-blue shop-carousel-prev" type="button"><i class="icon fa-chevron-left fa-fw"></i></button>',
draggable: true
}
},
inventory: {
card: $('.shop-inventory-card'),
info: $('.shop-inventory-info'),
items: $('.shop-inventory-list .shop-inventory-panel'),
proxy: $('.shop-inventory-proxy'),
classes: {
card: '.shop-inventory-card',
cardActive: 'shop-inventory-card-active',
cardPaused: 'shop-inventory-card-paused',
item: '.shop-inventory-item',
itemAnimate: 'shop-inventory-item-animate',
itemCount: '.shop-inventory-item-count',
itemTime: '.shop-inventory-item-time',
link: '.shop-inventory-link',
panel: '.shop-inventory-panel',
refund: '.shop-inventory-refund',
row: '.shop-inventory-row',
stack: '.shop-inventory-stack'
}
},
sketch: {
dots: [],
pool: [],
limit: 280,
timer: null,
timeout: 1500,
colours: ['#12a3eb', '#12a3eb', '#2172b8', '#18a39b', '#82c545', '#f8b739', '#f06045', '#ed2861', '#c12680', '#5d3191'],
drawing: null,
overlay: $('.shop-inventory-overlay'),
}
};
/**
* Set up carousel items.
*
* @return {void}
*/
studio.carousel.setup = function() {
let none = false,
data = studio.carousel.item.data();
if (data) {
none = !data.dots && !data.arrows;
delete data['shopCarouselData'];
}
// Register all carousel items
studio.carousel.items.each(function() {
let $footer = $(this).parent().next('.aps-panel-footer');
let slickData = $.extend({}, data, studio.carousel.data);
if ($(this).data('shop-carousel') === 'images') {
$.extend(slickData, {
arrows: false,
asNavFor: $footer,
dots: false,
fade: true,
slidesToScroll: 1,
slidesToShow: 1
});
} else {
$.extend(slickData, {
appendDots: $footer,
appendArrows: $footer
});
}
// Initiate a Slick instance
$(this).slick(slickData);
if ($(this).data('shop-carousel') === 'images') {
$footer.slick({
arrows: false,
asNavFor: this,
centerMode: true,
dots: false,
focusOnSelect: true,
slidesToScroll: 1,
slidesToShow: 3
});
}
// If there are no navigation arrows or dots, remove the footer
if (none) {
$footer.remove();
}
});
/**
* Remove the carousel data element.
*/
studio.carousel.item.remove();
};
studio.carousel.setup();
/**
* Show the loader for Shop AJAX requests.
*
* @return {void}
*/
studio.ajax.loading = function() {
if (!studio.ajax.spinner.is(':visible')) {
studio.ajax.spinner.fadeIn(100);
studio.ajax.clear();
studio.ajax.timer = setTimeout(studio.ajax.timeout, 60000)
}
};
/**
* Show the time out message for Shop AJAX requests.
*
* @return {void}
*/
studio.ajax.timeout = function() {
studio.ajax.message({
title: studio.ajax.alert.attr('data-l-err'),
html: studio.ajax.alert.attr('data-l-timeout-processing-req'),
type: 'error'
});
};
/**
* Get the localised message for Shop AJAX request errors.
*
* @param {string} attribute
* @return {string}
*/
studio.ajax.data.get = function(attribute) {
return $(this).attr(`data-ajax-error-${attribute}`);
};
/**
* Clear the timer for Shop AJAX requests.
*
* @return {void}
*/
studio.ajax.clear = function() {
if (studio.ajax.timer !== null) {
clearTimeout(studio.ajax.timer);
studio.ajax.timer = null;
}
};
/**
* The error handler for Shop AJAX requests.
*
* @param {Object} jqXHR
* @param {Object} jqXHR.responseJSON
* @param {String} jqXHR.responseText
* @param {string} textStatus
* @param {string} errorThrown
* @return {void}
*/
studio.ajax.error = function(jqXHR, textStatus, errorThrown) {
if (typeof console !== 'undefined' && console.log) {
console.log(`AJAX error. status: ${textStatus}, message: ${errorThrown}`);
}
studio.ajax.clear();
let responseText, errorText = '';
try {
responseText = JSON.parse(jqXHR.responseText);
responseText = responseText.message;
} catch (e) {}
if (typeof responseText === 'string' && responseText.length > 0) {
errorText = responseText;
} else if (typeof errorThrown === 'string' && errorThrown.length > 0) {
errorText = errorThrown;
} else {
errorText = studio.ajax.data.get(`text-${textStatus}`);
if (typeof errorText !== 'string' || !errorText.length) {
errorText = studio.ajax.data.get('text');
}
}
studio.ajax.message({
title: typeof jqXHR.responseJSON !== 'undefined' ? jqXHR.responseJSON.title : studio.ajax.data.get('title', false),
html: errorText,
type: 'error'
});
};
/**
* The success handler for Shop AJAX requests.
*
* @param {Object} r
* @param {function} callback
* @return {void}
*/
studio.ajax.success = function(r, callback) {
studio.ajax.clear();
/**
* @param {string} r.MESSAGE_BODY The message template body
* @param {string} r.YES_VALUE The "yes" language string
* @param {string} r.S_CONFIRM_ACTION The confirm_box() action
* @param {string} r.S_HIDDEN_FIELDS The confirm_box() hidden fields
*/
// If there is no confirm action (not a confirm_box())
if (typeof r.S_CONFIRM_ACTION === 'undefined') {
// Call the callback
if (typeof phpbb.ajaxCallbacks[callback] === 'function') {
phpbb.ajaxCallbacks[callback].call(this, r);
}
// Show the message
studio.ajax.message({
title: r.MESSAGE_TITLE,
html: r.MESSAGE_TEXT
});
} else {
// Show the confirm box
studio.ajax.message({
title: r.MESSAGE_TITLE,
html: r.MESSAGE_BODY,
type: 'question',
showCancelButton: true,
confirmButtonText: r.YES_VALUE
}).then((result) => {
// A button was pressed, was it the Confirm button?
if (result.value) {
let data = $('form', swal.getContent()).serialize();
data = data ? `${data}&` : '';
data = data + $(`<form>${r.S_HIDDEN_FIELDS}</form>`).serialize() + `&confirm=${r.YES_VALUE}`;
// Make the request
studio.ajax.request(r.S_CONFIRM_ACTION, callback, 'POST', data);
}
});
$('input', swal.getContent()).on('keydown', function(e) {
if (e.which === 13) {
swal.clickConfirm();
e.preventDefault();
return false;
}
});
}
};
/**
* Show a message for Shop AJAX requests.
*
* @param {Object} options
* @return {swal}
*/
studio.ajax.message = function(options) {
return swal.fire($.extend({
type: 'success',
cancelButtonClass: 'aps-button-alert aps-button-red',
confirmButtonClass: 'aps-button-alert aps-button-green shop-button-active',
showCloseButton: true,
buttonsStyling: false,
}, options));
};
/**
* Make a Shop AJAX request.
*
* @param {string} url
* @param {function} callback
* @param {string=} type
* @param {Object=} data
* @return {void}
*/
studio.ajax.request = function(url, callback, type, data) {
// Start the loading function
studio.ajax.loading();
// Make the request
let request = $.ajax({
url: url,
type: type || 'GET',
data: data || '',
error: studio.ajax.error,
success: function(r) {
studio.ajax.success(r, callback)
},
});
// No matter what the request returns, always stop the spinner
request.always(function() {
if (studio.ajax.spinner.is(':visible')){
studio.ajax.spinner.fadeOut(100);
}
});
};
/**
* Register all shop links for Shop AJAX requests.
*/
$(studio.body).on('click', studio.link, function(e) {
studio.ajax.request($(this).attr('href'), $(this).data('shop-link'));
e.preventDefault();
});
/**
* Remove an inventory item.
*
* @param {Object} r
* @return {void}
*/
studio.inventory.remove = function(r) {
let $items = $(`[data-shop-item="${r.id}"]`),
$section = $items.parents(studio.inventory.classes.panel),
$column = $section.parent('.aps-col'),
$row = $column.parent(studio.inventory.classes.row);
let $stack = $section.find(studio.inventory.classes.stack),
stack = typeof $stack !== 'undefined' ? parseInt($stack.text()) : false;
if (stack === false) {
$items.remove();
$section.remove();
$column.remove();
if ($row.children().length === 0) {
$row.remove();
}
} else {
$items.not($section.find($items)).remove();
if (r.index > 1) {
let replaceUrl = location.href.slice(0, -r.index.toString().length) + '1';
$section.find(studio.inventory.classes.link).attr('href', replaceUrl);
phpbb.history.replaceUrl(replaceUrl);
}
if (stack === 2) {
$stack.parent().remove();
} else {
$stack.text(stack - 1);
}
if (r.item) {
$items.replaceWith(r.item);
} else {
$section.draggable('destroy');
$section.addClass('shop-cursor-pointer');
}
}
};
/**
* Add AJAX callback for purchasing a Shop item.
*
* @param {Object} r The response object
* @param {string} r.points The new points value
* @param {number|bool} r.stock The new stock value
* @return {void}
*/
phpbb.addAjaxCallback('shop_purchase', function(r) {
$('.aps-menu > .aps-list-right > :first-child > span').text(r.points);
if (r.stock !== false) {
let $item = $(`[data-shop-item="${r.id}"]`);
$item.find('.shop-item-stock').text(r.stock);
if (r.stock === 0) {
$item.find('[data-shop-link="shop_purchase"]').remove();
}
}
});
/**
* Add AJAX callback for deleting a Shop item.
*
* @return {void}
*/
phpbb.addAjaxCallback('shop_inventory_delete', studio.inventory.remove);
/**
* Add AJAX callback for using a Shop item.
*
* @param {Object} r The response object
* @param {number} r.id The item identifier
* @param {Object} r.data The item data
* @param {number} r.data.use_count The item use count
* @param {string} r.data.use_time The item use time
* @param {bool} r.delete The delete indicator
* @param {bool} r.success The success indicator
* @param {string} r.file A window location for downloading a file
* @param {int} r.index The item stack index
* @return {void}
*/
phpbb.addAjaxCallback('shop_inventory_use', function(r) {
if (r.success) {
if (r.delete) {
studio.inventory.remove(r);
} else {
let $item = $(`[data-shop-item="${r.id}"]`),
$refund = $item.find(studio.inventory.classes.refund).remove();
$refund.remove();
$refund.next().removeClass('s2').addClass('s4');
if (r.data) {
$item.find(studio.inventory.classes.itemCount).text(r.data['use_count']);
$item.find(studio.inventory.classes.itemTime).text(r.data['use_time']).parent().show();
}
if (r.limit) {
let notice = '<div class="aps-col s12 shop-no-pad"><div class="aps-button-red shop-button-active shop-cursor-normal">' + r.limit + '</div></div>';
$item.find('> .aps-row > :first-child').after(notice);
$item.find('[data-shop-link="shop_inventory_use"]').remove();
}
}
if (r.file) {
setTimeout(function() {
window.location = r.file;
}, 1500);
}
}
});
/**
* Register the inventory items as draggables.
*
* @return {void}
*/
studio.inventory.items.each(function() {
$(this).draggable({
appendTo: studio.body,
containment: studio.body,
helper: 'clone',
scope: 'inventory',
snap: studio.inventory.classes.card,
snapMode: 'inner',
start: function(e, ui) {
studio.inventory.info.children().not(studio.inventory.proxy).remove();
$(this).draggable('instance').offset.click = {
left: Math.floor(ui.helper.width() / 2),
top: Math.floor(ui.helper.height() / 2)
};
studio.sketch.create(ui.helper);
},
stop: function() {
studio.sketch.timer = setTimeout(studio.sketch.destroy, studio.sketch.timeout);
}
});
});
/**
* Register the inventory 'placeholder card' as droppable.
*
* @return {void}
*/
studio.inventory.card.each(function() {
$(this).droppable({
activeClass: studio.inventory.classes.cardActive,
hoverClass: studio.inventory.classes.cardPaused,
scope: 'inventory',
drop: function(e, ui) {
let clone = ui.draggable.clone(false),
link = clone.find(studio.inventory.classes.link),
item = clone.find(studio.inventory.classes.item);
studio.inventory.info.append(clone);
clone.removeClass('ui-draggable ui-draggable-handle');
link.remove();
item.addClass(studio.inventory.classes.itemAnimate);
},
})
});
studio.sketch.dot = function(x, y, radius) {
this.init(x, y, radius);
};
studio.sketch.dot.prototype = {
init: function(x, y, radius) {
this.alive = true;
this.radius = radius || 10;
this.wander = 0.15;
this.theta = random(TWO_PI);
this.drag = 0.92;
this.color = '#12a3eb';
this.x = x || 0.0;
this.y = y || 0.0;
this.vx = 0.0;
this.vy = 0.0;
},
move: function() {
this.x += this.vx;
this.y += this.vy;
this.vx *= this.drag;
this.vy *= this.drag;
this.theta += random(-0.5, 0.5) * this.wander;
this.vx += Math.sin(this.theta) * 0.1;
this.vy += Math.cos(this.theta) * 0.1;
this.radius *= 0.96;
this.alive = this.radius > 0.5;
},
draw: function( ctx ) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, TWO_PI);
ctx.fillStyle = this.color;
ctx.fill();
}
};
studio.sketch.create = function(helper) {
studio.sketch.clear();
studio.sketch.drawing = Sketch.create({
container: studio.sketch.overlay[0],
eventTarget: helper[0],
retina: 'auto'
});
studio.sketch.drawing.spawn = function(x, y) {
let dot, theta, force;
if (studio.sketch.dots.length >= studio.sketch.limit) {
studio.sketch.pool.push(studio.sketch.dots.shift());
}
dot = studio.sketch.pool.length ? studio.sketch.pool.pop() : new studio.sketch.dot();
dot.init( x, y, random(5, 40));
dot.wander = random(0.5, 2.0);
dot.color = random(studio.sketch.colours);
dot.drag = random(0.9, 0.99);
theta = random(TWO_PI);
force = random(2, 8);
dot.vx = Math.sin(theta) * force;
dot.vy = Math.cos(theta) * force;
studio.sketch.dots.push(dot);
};
studio.sketch.drawing.update = function() {
let i, dot;
for (i = studio.sketch.dots.length - 1; i >= 0; i--) {
dot = studio.sketch.dots[i];
if (dot.alive) {
dot.move();
} else {
studio.sketch.pool.push(studio.sketch.dots.splice(i, 1)[0]);
}
}
};
studio.sketch.drawing.draw = function() {
studio.sketch.drawing.globalCompositeOperation = 'lighter';
for (let i = studio.sketch.dots.length - 1; i >= 0; i--) {
studio.sketch.dots[i].draw(studio.sketch.drawing);
}
};
studio.sketch.drawing.mousemove = function() {
let touch, max, i, j, n;
for (i = 0, n = studio.sketch.drawing.touches.length; i < n; i++) {
touch = studio.sketch.drawing.touches[i];
max = random(1, 4);
for (j = 0; j < max; j++) {
studio.sketch.drawing.spawn(touch.x, touch.y);
}
}
};
};
studio.sketch.clear = function() {
if (studio.sketch.timer !== null) {
clearTimeout(studio.sketch.timer);
studio.sketch.timer = null;
}
studio.sketch.destroy();
};
studio.sketch.destroy = function() {
if (studio.sketch.drawing !== null) {
studio.sketch.drawing.clear();
studio.sketch.drawing.destroy();
studio.sketch.drawing = null;
}
};
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,631 @@
/* Copyright (C) 2013 Justin Windle, http://soulwire.co.uk */
(function ( root, factory ) {
if ( typeof exports === 'object' ) {
// CommonJS like
module.exports = factory(root, root.document);
} else if ( typeof define === 'function' && define.amd ) {
// AMD
define( function() { return factory( root, root.document ); });
} else {
// Browser global
root.Sketch = factory( root, root.document );
}
}( typeof window !== "undefined" ? window : this, function ( window, document ) {
"use strict";
/*
----------------------------------------------------------------------
Config
----------------------------------------------------------------------
*/
var MATH_PROPS = 'E LN10 LN2 LOG2E LOG10E PI SQRT1_2 SQRT2 abs acos asin atan ceil cos exp floor log round sin sqrt tan atan2 pow max min'.split( ' ' );
var HAS_SKETCH = '__hasSketch';
var M = Math;
var CANVAS = 'canvas';
var WEBGL = 'webgl';
var DOM = 'dom';
var doc = document;
var win = window;
var instances = [];
var defaults = {
fullscreen: true,
autostart: true,
autoclear: true,
autopause: true,
container: doc.body,
interval: 1,
globals: true,
retina: false,
type: CANVAS
};
var keyMap = {
8: 'BACKSPACE',
9: 'TAB',
13: 'ENTER',
16: 'SHIFT',
27: 'ESCAPE',
32: 'SPACE',
37: 'LEFT',
38: 'UP',
39: 'RIGHT',
40: 'DOWN'
};
/*
----------------------------------------------------------------------
Utilities
----------------------------------------------------------------------
*/
function isArray( object ) {
return Object.prototype.toString.call( object ) == '[object Array]';
}
function isFunction( object ) {
return typeof object == 'function';
}
function isNumber( object ) {
return typeof object == 'number';
}
function isString( object ) {
return typeof object == 'string';
}
function keyName( code ) {
return keyMap[ code ] || String.fromCharCode( code );
}
function extend( target, source, overwrite ) {
for ( var key in source )
if ( overwrite || !( key in target ) )
target[ key ] = source[ key ];
return target;
}
function proxy( method, context ) {
return function() {
method.apply( context, arguments );
};
}
function clone( target ) {
var object = {};
for ( var key in target ) {
if ( key === 'webkitMovementX' || key === 'webkitMovementY' )
continue;
if ( isFunction( target[ key ] ) )
object[ key ] = proxy( target[ key ], target );
else
object[ key ] = target[ key ];
}
return object;
}
/*
----------------------------------------------------------------------
Constructor
----------------------------------------------------------------------
*/
function constructor( context ) {
var request, handler, target, parent, bounds, index, suffix, clock, node, copy, type, key, val, min, max, w, h;
var counter = 0;
var touches = [];
var resized = false;
var setup = false;
var ratio = win.devicePixelRatio || 1;
var isDiv = context.type == DOM;
var is2D = context.type == CANVAS;
var mouse = {
x: 0.0, y: 0.0,
ox: 0.0, oy: 0.0,
dx: 0.0, dy: 0.0
};
var eventMap = [
context.eventTarget || context.element,
pointer, 'mousedown', 'touchstart',
pointer, 'mousemove', 'touchmove',
pointer, 'mouseup', 'touchend',
pointer, 'click',
pointer, 'mouseout',
pointer, 'mouseover',
doc,
keypress, 'keydown', 'keyup',
win,
active, 'focus', 'blur',
resize, 'resize'
];
var keys = {}; for ( key in keyMap ) keys[ keyMap[ key ] ] = false;
function trigger( method ) {
if ( isFunction( method ) )
method.apply( context, [].splice.call( arguments, 1 ) );
}
function bind( on ) {
for ( index = 0; index < eventMap.length; index++ ) {
node = eventMap[ index ];
if ( isString( node ) )
target[ ( on ? 'add' : 'remove' ) + 'EventListener' ].call( target, node, handler, false );
else if ( isFunction( node ) )
handler = node;
else target = node;
}
}
function update() {
cAF( request );
request = rAF( update );
if ( !setup ) {
trigger( context.setup );
setup = isFunction( context.setup );
}
if ( !resized ) {
trigger( context.resize );
resized = isFunction( context.resize );
}
if ( context.running && !counter ) {
context.dt = ( clock = +new Date() ) - context.now;
context.millis += context.dt;
context.now = clock;
trigger( context.update );
// Pre draw
if ( is2D ) {
if ( context.retina ) {
context.save();
if (context.autoclear) {
context.scale( ratio, ratio );
}
}
if ( context.autoclear )
context.clear();
}
// Draw
trigger( context.draw );
// Post draw
if ( is2D && context.retina )
context.restore();
}
counter = ++counter % context.interval;
}
function resize() {
target = isDiv ? context.style : context.canvas;
suffix = isDiv ? 'px' : '';
w = context.width;
h = context.height;
if ( context.fullscreen ) {
h = context.height = win.innerHeight;
w = context.width = win.innerWidth;
}
if ( context.retina && is2D && ratio ) {
target.style.height = h + 'px';
target.style.width = w + 'px';
w *= ratio;
h *= ratio;
}
if ( target.height !== h )
target.height = h + suffix;
if ( target.width !== w )
target.width = w + suffix;
if ( is2D && !context.autoclear && context.retina )
context.scale( ratio, ratio );
if ( setup ) trigger( context.resize );
}
function align( touch, target ) {
bounds = target.getBoundingClientRect();
touch.x = touch.pageX - bounds.left - (win.scrollX || win.pageXOffset);
touch.y = touch.pageY - bounds.top - (win.scrollY || win.pageYOffset);
return touch;
}
function augment( touch, target ) {
align( touch, context.element );
target = target || {};
target.ox = target.x || touch.x;
target.oy = target.y || touch.y;
target.x = touch.x;
target.y = touch.y;
target.dx = target.x - target.ox;
target.dy = target.y - target.oy;
return target;
}
function process( event ) {
event.preventDefault();
copy = clone( event );
copy.originalEvent = event;
if ( copy.touches ) {
touches.length = copy.touches.length;
for ( index = 0; index < copy.touches.length; index++ )
touches[ index ] = augment( copy.touches[ index ], touches[ index ] );
} else {
touches.length = 0;
touches[0] = augment( copy, mouse );
}
extend( mouse, touches[0], true );
return copy;
}
function pointer( event ) {
event = process( event );
min = ( max = eventMap.indexOf( type = event.type ) ) - 1;
context.dragging =
/down|start/.test( type ) ? true :
/up|end/.test( type ) ? false :
context.dragging;
while( min )
isString( eventMap[ min ] ) ?
trigger( context[ eventMap[ min-- ] ], event ) :
isString( eventMap[ max ] ) ?
trigger( context[ eventMap[ max++ ] ], event ) :
min = 0;
}
function keypress( event ) {
key = event.keyCode;
val = event.type == 'keyup';
keys[ key ] = keys[ keyName( key ) ] = !val;
trigger( context[ event.type ], event );
}
function active( event ) {
if ( context.autopause )
( event.type == 'blur' ? stop : start )();
trigger( context[ event.type ], event );
}
// Public API
function start() {
context.now = +new Date();
context.running = true;
}
function stop() {
context.running = false;
}
function toggle() {
( context.running ? stop : start )();
}
function clear() {
if ( is2D )
context.clearRect( 0, 0, context.width * ratio, context.height * ratio );
}
function destroy() {
parent = context.element.parentNode;
index = instances.indexOf( context );
if ( parent ) parent.removeChild( context.element );
if ( ~index ) instances.splice( index, 1 );
bind( false );
stop();
}
extend( context, {
touches: touches,
mouse: mouse,
keys: keys,
dragging: false,
running: false,
millis: 0,
now: NaN,
dt: NaN,
destroy: destroy,
toggle: toggle,
clear: clear,
start: start,
stop: stop
});
instances.push( context );
return ( context.autostart && start(), bind( true ), resize(), update(), context );
}
/*
----------------------------------------------------------------------
Global API
----------------------------------------------------------------------
*/
var element, context, Sketch = {
CANVAS: CANVAS,
WEB_GL: WEBGL,
WEBGL: WEBGL,
DOM: DOM,
instances: instances,
install: function( context ) {
if ( !context[ HAS_SKETCH ] ) {
for ( var i = 0; i < MATH_PROPS.length; i++ )
context[ MATH_PROPS[i] ] = M[ MATH_PROPS[i] ];
extend( context, {
TWO_PI: M.PI * 2,
HALF_PI: M.PI / 2,
QUARTER_PI: M.PI / 4,
random: function( min, max ) {
if ( isArray( min ) )
return min[ ~~( M.random() * min.length ) ];
if ( !isNumber( max ) )
max = min || 1, min = 0;
return min + M.random() * ( max - min );
},
lerp: function( min, max, amount ) {
return min + amount * ( max - min );
},
map: function( num, minA, maxA, minB, maxB ) {
return ( num - minA ) / ( maxA - minA ) * ( maxB - minB ) + minB;
}
});
context[ HAS_SKETCH ] = true;
}
},
create: function( options ) {
options = extend( options || {}, defaults );
if ( options.globals ) Sketch.install( self );
element = options.element = options.element || doc.createElement( options.type === DOM ? 'div' : 'canvas' );
context = options.context = options.context || (function() {
switch( options.type ) {
case CANVAS:
return element.getContext( '2d', options );
case WEBGL:
return element.getContext( 'webgl', options ) || element.getContext( 'experimental-webgl', options );
case DOM:
return element.canvas = element;
}
})();
( options.container || doc.body ).appendChild( element );
return Sketch.augment( context, options );
},
augment: function( context, options ) {
options = extend( options || {}, defaults );
options.element = context.canvas || context;
options.element.className += ' sketch';
extend( context, options, true );
return constructor( context );
}
};
/*
----------------------------------------------------------------------
Shims
----------------------------------------------------------------------
*/
var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
var scope = self;
var then = 0;
var a = 'AnimationFrame';
var b = 'request' + a;
var c = 'cancel' + a;
var rAF = scope[ b ];
var cAF = scope[ c ];
for ( var i = 0; i < vendors.length && !rAF; i++ ) {
rAF = scope[ vendors[ i ] + 'Request' + a ];
cAF = scope[ vendors[ i ] + 'Cancel' + a ];
}
scope[ b ] = rAF = rAF || function( callback ) {
var now = +new Date();
var dt = M.max( 0, 16 - ( now - then ) );
var id = setTimeout( function() {
callback( now + dt );
}, dt );
then = now + dt;
return id;
};
scope[ c ] = cAF = cAF || function( id ) {
clearTimeout( id );
};
/*
----------------------------------------------------------------------
Output
----------------------------------------------------------------------
*/
return Sketch;
}));

View File

@@ -0,0 +1,2 @@
/* Copyright (C) 2013 Justin Windle, http://soulwire.co.uk */
!function(e,t){"object"==typeof exports?module.exports=t(e,e.document):"function"==typeof define&&define.amd?define(function(){return t(e,e.document)}):e.Sketch=t(e,e.document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(e){return"[object Array]"==Object.prototype.toString.call(e)}function o(e){return"function"==typeof e}function r(e){return"number"==typeof e}function i(e){return"string"==typeof e}function u(e){return C[e]||String.fromCharCode(e)}function a(e,t,n){for(var o in t)!n&&o in e||(e[o]=t[o]);return e}function c(e,t){return function(){e.apply(t,arguments)}}function l(e){var t={};for(var n in e)"webkitMovementX"!==n&&"webkitMovementY"!==n&&(o(e[n])?t[n]=c(e[n],e):t[n]=e[n]);return t}function s(e){function t(t){o(t)&&t.apply(e,[].splice.call(arguments,1))}function n(e){for(_=0;_<ee.length;_++)B=ee[_],i(B)?S[(e?"add":"remove")+"EventListener"].call(S,B,N,!1):o(B)?N=B:S=B}function r(){I(A),A=R(r),K||(t(e.setup),K=o(e.setup)),U||(t(e.resize),U=o(e.resize)),e.running&&!q&&(e.dt=(z=+new Date)-e.now,e.millis+=e.dt,e.now=z,t(e.update),Z&&(e.retina&&(e.save(),e.autoclear&&e.scale(V,V)),e.autoclear&&e.clear()),t(e.draw),Z&&e.retina&&e.restore()),q=++q%e.interval}function c(){S=J?e.style:e.canvas,D=J?"px":"",Y=e.width,j=e.height,e.fullscreen&&(j=e.height=v.innerHeight,Y=e.width=v.innerWidth),e.retina&&Z&&V&&(S.style.height=j+"px",S.style.width=Y+"px",Y*=V,j*=V),S.height!==j&&(S.height=j+D),S.width!==Y&&(S.width=Y+D),Z&&!e.autoclear&&e.retina&&e.scale(V,V),K&&t(e.resize)}function s(e,t){return L=t.getBoundingClientRect(),e.x=e.pageX-L.left-(v.scrollX||v.pageXOffset),e.y=e.pageY-L.top-(v.scrollY||v.pageYOffset),e}function f(t,n){return s(t,e.element),n=n||{},n.ox=n.x||t.x,n.oy=n.y||t.y,n.x=t.x,n.y=t.y,n.dx=n.x-n.ox,n.dy=n.y-n.oy,n}function d(e){if(e.preventDefault(),G=l(e),G.originalEvent=e,G.touches)for(Q.length=G.touches.length,_=0;_<G.touches.length;_++)Q[_]=f(G.touches[_],Q[_]);else Q.length=0,Q[0]=f(G,$);return a($,Q[0],!0),G}function p(n){for(n=d(n),M=(X=ee.indexOf(W=n.type))-1,e.dragging=!!/down|start/.test(W)||!/up|end/.test(W)&&e.dragging;M;)i(ee[M])?t(e[ee[M--]],n):i(ee[X])?t(e[ee[X++]],n):M=0}function g(n){F=n.keyCode,H="keyup"==n.type,te[F]=te[u(F)]=!H,t(e[n.type],n)}function m(n){e.autopause&&("blur"==n.type?E:y)(),t(e[n.type],n)}function y(){e.now=+new Date,e.running=!0}function E(){e.running=!1}function k(){(e.running?E:y)()}function P(){Z&&e.clearRect(0,0,e.width*V,e.height*V)}function T(){O=e.element.parentNode,_=b.indexOf(e),O&&O.removeChild(e.element),~_&&b.splice(_,1),n(!1),E()}var A,N,S,O,L,_,D,z,B,G,W,F,H,M,X,Y,j,q=0,Q=[],U=!1,K=!1,V=v.devicePixelRatio||1,J=e.type==w,Z=e.type==h,$={x:0,y:0,ox:0,oy:0,dx:0,dy:0},ee=[e.eventTarget||e.element,p,"mousedown","touchstart",p,"mousemove","touchmove",p,"mouseup","touchend",p,"click",p,"mouseout",p,"mouseover",x,g,"keydown","keyup",v,m,"focus","blur",c,"resize"],te={};for(F in C)te[C[F]]=!1;return a(e,{touches:Q,mouse:$,keys:te,dragging:!1,running:!1,millis:0,now:NaN,dt:NaN,destroy:T,toggle:k,clear:P,start:y,stop:E}),b.push(e),e.autostart&&y(),n(!0),c(),r(),e}for(var f,d,p="E LN10 LN2 LOG2E LOG10E PI SQRT1_2 SQRT2 abs acos asin atan ceil cos exp floor log round sin sqrt tan atan2 pow max min".split(" "),g="__hasSketch",m=Math,h="canvas",y="webgl",w="dom",x=t,v=e,b=[],E={fullscreen:!0,autostart:!0,autoclear:!0,autopause:!0,container:x.body,interval:1,globals:!0,retina:!1,type:h},C={8:"BACKSPACE",9:"TAB",13:"ENTER",16:"SHIFT",27:"ESCAPE",32:"SPACE",37:"LEFT",38:"UP",39:"RIGHT",40:"DOWN"},k={CANVAS:h,WEB_GL:y,WEBGL:y,DOM:w,instances:b,install:function(e){if(!e[g]){for(var t=0;t<p.length;t++)e[p[t]]=m[p[t]];a(e,{TWO_PI:2*m.PI,HALF_PI:m.PI/2,QUARTER_PI:m.PI/4,random:function(e,t){return n(e)?e[~~(m.random()*e.length)]:(r(t)||(t=e||1,e=0),e+m.random()*(t-e))},lerp:function(e,t,n){return e+n*(t-e)},map:function(e,t,n,o,r){return(e-t)/(n-t)*(r-o)+o}}),e[g]=!0}},create:function(e){return e=a(e||{},E),e.globals&&k.install(self),f=e.element=e.element||x.createElement(e.type===w?"div":"canvas"),d=e.context=e.context||function(){switch(e.type){case h:return f.getContext("2d",e);case y:return f.getContext("webgl",e)||f.getContext("experimental-webgl",e);case w:return f.canvas=f}}(),(e.container||x.body).appendChild(f),k.augment(d,e)},augment:function(e,t){return t=a(t||{},E),t.element=e.canvas||e,t.element.className+=" sketch",a(e,t,!0),s(e)}},P=["ms","moz","webkit","o"],T=self,A=0,N="AnimationFrame",S="request"+N,O="cancel"+N,R=T[S],I=T[O],L=0;L<P.length&&!R;L++)R=T[P[L]+"Request"+N],I=T[P[L]+"Cancel"+N];return T[S]=R=R||function(e){var t=+new Date,n=m.max(0,16-(t-A)),o=setTimeout(function(){e(t+n)},n);return A=t+n,o},T[O]=I=I||function(e){clearTimeout(e)},k});

File diff suppressed because one or more lines are too long