Compare commits

..

2 Commits

Author SHA1 Message Date
3eada29d4c Merge branch 'master' of https://repo.hurasoft.com/tieptk/bestpc 2025-05-28 15:33:22 +07:00
fdda1c345f upload 28/5 2025-05-28 15:30:26 +07:00
252 changed files with 35084 additions and 1237 deletions

3081
.vite/deps/@fancyapps_ui.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

61
.vite/deps/_metadata.json Normal file
View File

@@ -0,0 +1,61 @@
{
"hash": "ce7a0443",
"configHash": "8bcd3e19",
"lockfileHash": "1d8bf9b4",
"browserHash": "b15efe69",
"optimized": {
"@fancyapps/ui": {
"src": "../../node_modules/@fancyapps/ui/dist/index.esm.js",
"file": "@fancyapps_ui.js",
"fileHash": "0e91493d",
"needsInterop": false
},
"preact": {
"src": "../../node_modules/preact/dist/preact.module.js",
"file": "preact.js",
"fileHash": "b331e8bf",
"needsInterop": false
},
"preact-iso": {
"src": "../../node_modules/preact-iso/src/index.js",
"file": "preact-iso.js",
"fileHash": "da0bf0a6",
"needsInterop": false
},
"react": {
"src": "../../node_modules/react/index.js",
"file": "react.js",
"fileHash": "8051360a",
"needsInterop": true
},
"swiper/modules": {
"src": "../../node_modules/swiper/modules/index.mjs",
"file": "swiper_modules.js",
"fileHash": "ab031693",
"needsInterop": false
},
"swiper/react": {
"src": "../../node_modules/swiper/swiper-react.mjs",
"file": "swiper_react.js",
"fileHash": "8a08080a",
"needsInterop": false
}
},
"chunks": {
"chunk-KS2M7ZJI": {
"file": "chunk-KS2M7ZJI.js"
},
"chunk-XLOWEJT4": {
"file": "chunk-XLOWEJT4.js"
},
"prerender-2A2BKSYN": {
"file": "prerender-2A2BKSYN.js"
},
"chunk-WFLWNDNR": {
"file": "chunk-WFLWNDNR.js"
},
"chunk-5WRI5ZAA": {
"file": "chunk-5WRI5ZAA.js"
}
}
}

View File

@@ -0,0 +1,30 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
export {
__commonJS,
__toESM
};

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

View File

@@ -0,0 +1,972 @@
import {
__commonJS
} from "./chunk-5WRI5ZAA.js";
// node_modules/react/cjs/react.development.js
var require_react_development = __commonJS({
"node_modules/react/cjs/react.development.js"(exports, module) {
"use strict";
(function() {
function defineDeprecationWarning(methodName, info) {
Object.defineProperty(Component.prototype, methodName, {
get: function() {
console.warn(
"%s(...) is deprecated in plain JavaScript React classes. %s",
info[0],
info[1]
);
}
});
}
function getIteratorFn(maybeIterable) {
if (null === maybeIterable || "object" !== typeof maybeIterable)
return null;
maybeIterable = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable["@@iterator"];
return "function" === typeof maybeIterable ? maybeIterable : null;
}
function warnNoop(publicInstance, callerName) {
publicInstance = (publicInstance = publicInstance.constructor) && (publicInstance.displayName || publicInstance.name) || "ReactClass";
var warningKey = publicInstance + "." + callerName;
didWarnStateUpdateForUnmountedComponent[warningKey] || (console.error(
"Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",
callerName,
publicInstance
), didWarnStateUpdateForUnmountedComponent[warningKey] = true);
}
function Component(props, context, updater) {
this.props = props;
this.context = context;
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
}
function ComponentDummy() {
}
function PureComponent(props, context, updater) {
this.props = props;
this.context = context;
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
}
function testStringCoercion(value) {
return "" + value;
}
function checkKeyStringCoercion(value) {
try {
testStringCoercion(value);
var JSCompiler_inline_result = false;
} catch (e) {
JSCompiler_inline_result = true;
}
if (JSCompiler_inline_result) {
JSCompiler_inline_result = console;
var JSCompiler_temp_const = JSCompiler_inline_result.error;
var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
JSCompiler_temp_const.call(
JSCompiler_inline_result,
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
JSCompiler_inline_result$jscomp$0
);
return testStringCoercion(value);
}
}
function getComponentNameFromType(type) {
if (null == type) return null;
if ("function" === typeof type)
return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
if ("string" === typeof type) return type;
switch (type) {
case REACT_FRAGMENT_TYPE:
return "Fragment";
case REACT_PROFILER_TYPE:
return "Profiler";
case REACT_STRICT_MODE_TYPE:
return "StrictMode";
case REACT_SUSPENSE_TYPE:
return "Suspense";
case REACT_SUSPENSE_LIST_TYPE:
return "SuspenseList";
case REACT_ACTIVITY_TYPE:
return "Activity";
}
if ("object" === typeof type)
switch ("number" === typeof type.tag && console.error(
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
), type.$$typeof) {
case REACT_PORTAL_TYPE:
return "Portal";
case REACT_CONTEXT_TYPE:
return (type.displayName || "Context") + ".Provider";
case REACT_CONSUMER_TYPE:
return (type._context.displayName || "Context") + ".Consumer";
case REACT_FORWARD_REF_TYPE:
var innerType = type.render;
type = type.displayName;
type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
return type;
case REACT_MEMO_TYPE:
return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
case REACT_LAZY_TYPE:
innerType = type._payload;
type = type._init;
try {
return getComponentNameFromType(type(innerType));
} catch (x) {
}
}
return null;
}
function getTaskName(type) {
if (type === REACT_FRAGMENT_TYPE) return "<>";
if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE)
return "<...>";
try {
var name = getComponentNameFromType(type);
return name ? "<" + name + ">" : "<...>";
} catch (x) {
return "<...>";
}
}
function getOwner() {
var dispatcher = ReactSharedInternals.A;
return null === dispatcher ? null : dispatcher.getOwner();
}
function UnknownOwner() {
return Error("react-stack-top-frame");
}
function hasValidKey(config) {
if (hasOwnProperty.call(config, "key")) {
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
if (getter && getter.isReactWarning) return false;
}
return void 0 !== config.key;
}
function defineKeyPropWarningGetter(props, displayName) {
function warnAboutAccessingKey() {
specialPropKeyWarningShown || (specialPropKeyWarningShown = true, console.error(
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
displayName
));
}
warnAboutAccessingKey.isReactWarning = true;
Object.defineProperty(props, "key", {
get: warnAboutAccessingKey,
configurable: true
});
}
function elementRefGetterWithDeprecationWarning() {
var componentName = getComponentNameFromType(this.type);
didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = true, console.error(
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
));
componentName = this.props.ref;
return void 0 !== componentName ? componentName : null;
}
function ReactElement(type, key, self, source, owner, props, debugStack, debugTask) {
self = props.ref;
type = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
props,
_owner: owner
};
null !== (void 0 !== self ? self : null) ? Object.defineProperty(type, "ref", {
enumerable: false,
get: elementRefGetterWithDeprecationWarning
}) : Object.defineProperty(type, "ref", { enumerable: false, value: null });
type._store = {};
Object.defineProperty(type._store, "validated", {
configurable: false,
enumerable: false,
writable: true,
value: 0
});
Object.defineProperty(type, "_debugInfo", {
configurable: false,
enumerable: false,
writable: true,
value: null
});
Object.defineProperty(type, "_debugStack", {
configurable: false,
enumerable: false,
writable: true,
value: debugStack
});
Object.defineProperty(type, "_debugTask", {
configurable: false,
enumerable: false,
writable: true,
value: debugTask
});
Object.freeze && (Object.freeze(type.props), Object.freeze(type));
return type;
}
function cloneAndReplaceKey(oldElement, newKey) {
newKey = ReactElement(
oldElement.type,
newKey,
void 0,
void 0,
oldElement._owner,
oldElement.props,
oldElement._debugStack,
oldElement._debugTask
);
oldElement._store && (newKey._store.validated = oldElement._store.validated);
return newKey;
}
function isValidElement(object) {
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
}
function escape(key) {
var escaperLookup = { "=": "=0", ":": "=2" };
return "$" + key.replace(/[=:]/g, function(match) {
return escaperLookup[match];
});
}
function getElementKey(element, index) {
return "object" === typeof element && null !== element && null != element.key ? (checkKeyStringCoercion(element.key), escape("" + element.key)) : index.toString(36);
}
function noop$1() {
}
function resolveThenable(thenable) {
switch (thenable.status) {
case "fulfilled":
return thenable.value;
case "rejected":
throw thenable.reason;
default:
switch ("string" === typeof thenable.status ? thenable.then(noop$1, noop$1) : (thenable.status = "pending", thenable.then(
function(fulfilledValue) {
"pending" === thenable.status && (thenable.status = "fulfilled", thenable.value = fulfilledValue);
},
function(error) {
"pending" === thenable.status && (thenable.status = "rejected", thenable.reason = error);
}
)), thenable.status) {
case "fulfilled":
return thenable.value;
case "rejected":
throw thenable.reason;
}
}
throw thenable;
}
function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
var type = typeof children;
if ("undefined" === type || "boolean" === type) children = null;
var invokeCallback = false;
if (null === children) invokeCallback = true;
else
switch (type) {
case "bigint":
case "string":
case "number":
invokeCallback = true;
break;
case "object":
switch (children.$$typeof) {
case REACT_ELEMENT_TYPE:
case REACT_PORTAL_TYPE:
invokeCallback = true;
break;
case REACT_LAZY_TYPE:
return invokeCallback = children._init, mapIntoArray(
invokeCallback(children._payload),
array,
escapedPrefix,
nameSoFar,
callback
);
}
}
if (invokeCallback) {
invokeCallback = children;
callback = callback(invokeCallback);
var childKey = "" === nameSoFar ? "." + getElementKey(invokeCallback, 0) : nameSoFar;
isArrayImpl(callback) ? (escapedPrefix = "", null != childKey && (escapedPrefix = childKey.replace(userProvidedKeyEscapeRegex, "$&/") + "/"), mapIntoArray(callback, array, escapedPrefix, "", function(c) {
return c;
})) : null != callback && (isValidElement(callback) && (null != callback.key && (invokeCallback && invokeCallback.key === callback.key || checkKeyStringCoercion(callback.key)), escapedPrefix = cloneAndReplaceKey(
callback,
escapedPrefix + (null == callback.key || invokeCallback && invokeCallback.key === callback.key ? "" : ("" + callback.key).replace(
userProvidedKeyEscapeRegex,
"$&/"
) + "/") + childKey
), "" !== nameSoFar && null != invokeCallback && isValidElement(invokeCallback) && null == invokeCallback.key && invokeCallback._store && !invokeCallback._store.validated && (escapedPrefix._store.validated = 2), callback = escapedPrefix), array.push(callback));
return 1;
}
invokeCallback = 0;
childKey = "" === nameSoFar ? "." : nameSoFar + ":";
if (isArrayImpl(children))
for (var i = 0; i < children.length; i++)
nameSoFar = children[i], type = childKey + getElementKey(nameSoFar, i), invokeCallback += mapIntoArray(
nameSoFar,
array,
escapedPrefix,
type,
callback
);
else if (i = getIteratorFn(children), "function" === typeof i)
for (i === children.entries && (didWarnAboutMaps || console.warn(
"Using Maps as children is not supported. Use an array of keyed ReactElements instead."
), didWarnAboutMaps = true), children = i.call(children), i = 0; !(nameSoFar = children.next()).done; )
nameSoFar = nameSoFar.value, type = childKey + getElementKey(nameSoFar, i++), invokeCallback += mapIntoArray(
nameSoFar,
array,
escapedPrefix,
type,
callback
);
else if ("object" === type) {
if ("function" === typeof children.then)
return mapIntoArray(
resolveThenable(children),
array,
escapedPrefix,
nameSoFar,
callback
);
array = String(children);
throw Error(
"Objects are not valid as a React child (found: " + ("[object Object]" === array ? "object with keys {" + Object.keys(children).join(", ") + "}" : array) + "). If you meant to render a collection of children, use an array instead."
);
}
return invokeCallback;
}
function mapChildren(children, func, context) {
if (null == children) return children;
var result = [], count = 0;
mapIntoArray(children, result, "", "", function(child) {
return func.call(context, child, count++);
});
return result;
}
function lazyInitializer(payload) {
if (-1 === payload._status) {
var ctor = payload._result;
ctor = ctor();
ctor.then(
function(moduleObject) {
if (0 === payload._status || -1 === payload._status)
payload._status = 1, payload._result = moduleObject;
},
function(error) {
if (0 === payload._status || -1 === payload._status)
payload._status = 2, payload._result = error;
}
);
-1 === payload._status && (payload._status = 0, payload._result = ctor);
}
if (1 === payload._status)
return ctor = payload._result, void 0 === ctor && console.error(
"lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))\n\nDid you accidentally put curly braces around the import?",
ctor
), "default" in ctor || console.error(
"lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))",
ctor
), ctor.default;
throw payload._result;
}
function resolveDispatcher() {
var dispatcher = ReactSharedInternals.H;
null === dispatcher && console.error(
"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem."
);
return dispatcher;
}
function noop() {
}
function enqueueTask(task) {
if (null === enqueueTaskImpl)
try {
var requireString = ("require" + Math.random()).slice(0, 7);
enqueueTaskImpl = (module && module[requireString]).call(
module,
"timers"
).setImmediate;
} catch (_err) {
enqueueTaskImpl = function(callback) {
false === didWarnAboutMessageChannel && (didWarnAboutMessageChannel = true, "undefined" === typeof MessageChannel && console.error(
"This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning."
));
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage(void 0);
};
}
return enqueueTaskImpl(task);
}
function aggregateErrors(errors) {
return 1 < errors.length && "function" === typeof AggregateError ? new AggregateError(errors) : errors[0];
}
function popActScope(prevActQueue, prevActScopeDepth) {
prevActScopeDepth !== actScopeDepth - 1 && console.error(
"You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. "
);
actScopeDepth = prevActScopeDepth;
}
function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {
var queue = ReactSharedInternals.actQueue;
if (null !== queue)
if (0 !== queue.length)
try {
flushActQueue(queue);
enqueueTask(function() {
return recursivelyFlushAsyncActWork(returnValue, resolve, reject);
});
return;
} catch (error) {
ReactSharedInternals.thrownErrors.push(error);
}
else ReactSharedInternals.actQueue = null;
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve(returnValue);
}
function flushActQueue(queue) {
if (!isFlushing) {
isFlushing = true;
var i = 0;
try {
for (; i < queue.length; i++) {
var callback = queue[i];
do {
ReactSharedInternals.didUsePromise = false;
var continuation = callback(false);
if (null !== continuation) {
if (ReactSharedInternals.didUsePromise) {
queue[i] = callback;
queue.splice(0, i);
return;
}
callback = continuation;
} else break;
} while (1);
}
queue.length = 0;
} catch (error) {
queue.splice(0, i + 1), ReactSharedInternals.thrownErrors.push(error);
} finally {
isFlushing = false;
}
}
}
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler");
Symbol.for("react.provider");
var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), MAYBE_ITERATOR_SYMBOL = Symbol.iterator, didWarnStateUpdateForUnmountedComponent = {}, ReactNoopUpdateQueue = {
isMounted: function() {
return false;
},
enqueueForceUpdate: function(publicInstance) {
warnNoop(publicInstance, "forceUpdate");
},
enqueueReplaceState: function(publicInstance) {
warnNoop(publicInstance, "replaceState");
},
enqueueSetState: function(publicInstance) {
warnNoop(publicInstance, "setState");
}
}, assign = Object.assign, emptyObject = {};
Object.freeze(emptyObject);
Component.prototype.isReactComponent = {};
Component.prototype.setState = function(partialState, callback) {
if ("object" !== typeof partialState && "function" !== typeof partialState && null != partialState)
throw Error(
"takes an object of state variables to update or a function which returns an object of state variables."
);
this.updater.enqueueSetState(this, partialState, callback, "setState");
};
Component.prototype.forceUpdate = function(callback) {
this.updater.enqueueForceUpdate(this, callback, "forceUpdate");
};
var deprecatedAPIs = {
isMounted: [
"isMounted",
"Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."
],
replaceState: [
"replaceState",
"Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."
]
}, fnName;
for (fnName in deprecatedAPIs)
deprecatedAPIs.hasOwnProperty(fnName) && defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
ComponentDummy.prototype = Component.prototype;
deprecatedAPIs = PureComponent.prototype = new ComponentDummy();
deprecatedAPIs.constructor = PureComponent;
assign(deprecatedAPIs, Component.prototype);
deprecatedAPIs.isPureReactComponent = true;
var isArrayImpl = Array.isArray, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = {
H: null,
A: null,
T: null,
S: null,
V: null,
actQueue: null,
isBatchingLegacy: false,
didScheduleLegacyUpdate: false,
didUsePromise: false,
thrownErrors: [],
getCurrentStack: null,
recentlyCreatedOwnerStacks: 0
}, hasOwnProperty = Object.prototype.hasOwnProperty, createTask = console.createTask ? console.createTask : function() {
return null;
};
deprecatedAPIs = {
"react-stack-bottom-frame": function(callStackForError) {
return callStackForError();
}
};
var specialPropKeyWarningShown, didWarnAboutOldJSXRuntime;
var didWarnAboutElementRef = {};
var unknownOwnerDebugStack = deprecatedAPIs["react-stack-bottom-frame"].bind(deprecatedAPIs, UnknownOwner)();
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
var didWarnAboutMaps = false, userProvidedKeyEscapeRegex = /\/+/g, reportGlobalError = "function" === typeof reportError ? reportError : function(error) {
if ("object" === typeof window && "function" === typeof window.ErrorEvent) {
var event = new window.ErrorEvent("error", {
bubbles: true,
cancelable: true,
message: "object" === typeof error && null !== error && "string" === typeof error.message ? String(error.message) : String(error),
error
});
if (!window.dispatchEvent(event)) return;
} else if ("object" === typeof process && "function" === typeof process.emit) {
process.emit("uncaughtException", error);
return;
}
console.error(error);
}, didWarnAboutMessageChannel = false, enqueueTaskImpl = null, actScopeDepth = 0, didWarnNoAwaitAct = false, isFlushing = false, queueSeveralMicrotasks = "function" === typeof queueMicrotask ? function(callback) {
queueMicrotask(function() {
return queueMicrotask(callback);
});
} : enqueueTask;
deprecatedAPIs = Object.freeze({
__proto__: null,
c: function(size) {
return resolveDispatcher().useMemoCache(size);
}
});
exports.Children = {
map: mapChildren,
forEach: function(children, forEachFunc, forEachContext) {
mapChildren(
children,
function() {
forEachFunc.apply(this, arguments);
},
forEachContext
);
},
count: function(children) {
var n = 0;
mapChildren(children, function() {
n++;
});
return n;
},
toArray: function(children) {
return mapChildren(children, function(child) {
return child;
}) || [];
},
only: function(children) {
if (!isValidElement(children))
throw Error(
"React.Children.only expected to receive a single React element child."
);
return children;
}
};
exports.Component = Component;
exports.Fragment = REACT_FRAGMENT_TYPE;
exports.Profiler = REACT_PROFILER_TYPE;
exports.PureComponent = PureComponent;
exports.StrictMode = REACT_STRICT_MODE_TYPE;
exports.Suspense = REACT_SUSPENSE_TYPE;
exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = ReactSharedInternals;
exports.__COMPILER_RUNTIME = deprecatedAPIs;
exports.act = function(callback) {
var prevActQueue = ReactSharedInternals.actQueue, prevActScopeDepth = actScopeDepth;
actScopeDepth++;
var queue = ReactSharedInternals.actQueue = null !== prevActQueue ? prevActQueue : [], didAwaitActCall = false;
try {
var result = callback();
} catch (error) {
ReactSharedInternals.thrownErrors.push(error);
}
if (0 < ReactSharedInternals.thrownErrors.length)
throw popActScope(prevActQueue, prevActScopeDepth), callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
if (null !== result && "object" === typeof result && "function" === typeof result.then) {
var thenable = result;
queueSeveralMicrotasks(function() {
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error(
"You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"
));
});
return {
then: function(resolve, reject) {
didAwaitActCall = true;
thenable.then(
function(returnValue) {
popActScope(prevActQueue, prevActScopeDepth);
if (0 === prevActScopeDepth) {
try {
flushActQueue(queue), enqueueTask(function() {
return recursivelyFlushAsyncActWork(
returnValue,
resolve,
reject
);
});
} catch (error$0) {
ReactSharedInternals.thrownErrors.push(error$0);
}
if (0 < ReactSharedInternals.thrownErrors.length) {
var _thrownError = aggregateErrors(
ReactSharedInternals.thrownErrors
);
ReactSharedInternals.thrownErrors.length = 0;
reject(_thrownError);
}
} else resolve(returnValue);
},
function(error) {
popActScope(prevActQueue, prevActScopeDepth);
0 < ReactSharedInternals.thrownErrors.length ? (error = aggregateErrors(
ReactSharedInternals.thrownErrors
), ReactSharedInternals.thrownErrors.length = 0, reject(error)) : reject(error);
}
);
}
};
}
var returnValue$jscomp$0 = result;
popActScope(prevActQueue, prevActScopeDepth);
0 === prevActScopeDepth && (flushActQueue(queue), 0 !== queue.length && queueSeveralMicrotasks(function() {
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error(
"A component suspended inside an `act` scope, but the `act` call was not awaited. When testing React components that depend on asynchronous data, you must await the result:\n\nawait act(() => ...)"
));
}), ReactSharedInternals.actQueue = null);
if (0 < ReactSharedInternals.thrownErrors.length)
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
return {
then: function(resolve, reject) {
didAwaitActCall = true;
0 === prevActScopeDepth ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
return recursivelyFlushAsyncActWork(
returnValue$jscomp$0,
resolve,
reject
);
})) : resolve(returnValue$jscomp$0);
}
};
};
exports.cache = function(fn) {
return function() {
return fn.apply(null, arguments);
};
};
exports.captureOwnerStack = function() {
var getCurrentStack = ReactSharedInternals.getCurrentStack;
return null === getCurrentStack ? null : getCurrentStack();
};
exports.cloneElement = function(element, config, children) {
if (null === element || void 0 === element)
throw Error(
"The argument must be a React element, but you passed " + element + "."
);
var props = assign({}, element.props), key = element.key, owner = element._owner;
if (null != config) {
var JSCompiler_inline_result;
a: {
if (hasOwnProperty.call(config, "ref") && (JSCompiler_inline_result = Object.getOwnPropertyDescriptor(
config,
"ref"
).get) && JSCompiler_inline_result.isReactWarning) {
JSCompiler_inline_result = false;
break a;
}
JSCompiler_inline_result = void 0 !== config.ref;
}
JSCompiler_inline_result && (owner = getOwner());
hasValidKey(config) && (checkKeyStringCoercion(config.key), key = "" + config.key);
for (propName in config)
!hasOwnProperty.call(config, propName) || "key" === propName || "__self" === propName || "__source" === propName || "ref" === propName && void 0 === config.ref || (props[propName] = config[propName]);
}
var propName = arguments.length - 2;
if (1 === propName) props.children = children;
else if (1 < propName) {
JSCompiler_inline_result = Array(propName);
for (var i = 0; i < propName; i++)
JSCompiler_inline_result[i] = arguments[i + 2];
props.children = JSCompiler_inline_result;
}
props = ReactElement(
element.type,
key,
void 0,
void 0,
owner,
props,
element._debugStack,
element._debugTask
);
for (key = 2; key < arguments.length; key++)
owner = arguments[key], isValidElement(owner) && owner._store && (owner._store.validated = 1);
return props;
};
exports.createContext = function(defaultValue) {
defaultValue = {
$$typeof: REACT_CONTEXT_TYPE,
_currentValue: defaultValue,
_currentValue2: defaultValue,
_threadCount: 0,
Provider: null,
Consumer: null
};
defaultValue.Provider = defaultValue;
defaultValue.Consumer = {
$$typeof: REACT_CONSUMER_TYPE,
_context: defaultValue
};
defaultValue._currentRenderer = null;
defaultValue._currentRenderer2 = null;
return defaultValue;
};
exports.createElement = function(type, config, children) {
for (var i = 2; i < arguments.length; i++) {
var node = arguments[i];
isValidElement(node) && node._store && (node._store.validated = 1);
}
i = {};
node = null;
if (null != config)
for (propName in didWarnAboutOldJSXRuntime || !("__self" in config) || "key" in config || (didWarnAboutOldJSXRuntime = true, console.warn(
"Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform"
)), hasValidKey(config) && (checkKeyStringCoercion(config.key), node = "" + config.key), config)
hasOwnProperty.call(config, propName) && "key" !== propName && "__self" !== propName && "__source" !== propName && (i[propName] = config[propName]);
var childrenLength = arguments.length - 2;
if (1 === childrenLength) i.children = children;
else if (1 < childrenLength) {
for (var childArray = Array(childrenLength), _i = 0; _i < childrenLength; _i++)
childArray[_i] = arguments[_i + 2];
Object.freeze && Object.freeze(childArray);
i.children = childArray;
}
if (type && type.defaultProps)
for (propName in childrenLength = type.defaultProps, childrenLength)
void 0 === i[propName] && (i[propName] = childrenLength[propName]);
node && defineKeyPropWarningGetter(
i,
"function" === typeof type ? type.displayName || type.name || "Unknown" : type
);
var propName = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
return ReactElement(
type,
node,
void 0,
void 0,
getOwner(),
i,
propName ? Error("react-stack-top-frame") : unknownOwnerDebugStack,
propName ? createTask(getTaskName(type)) : unknownOwnerDebugTask
);
};
exports.createRef = function() {
var refObject = { current: null };
Object.seal(refObject);
return refObject;
};
exports.forwardRef = function(render) {
null != render && render.$$typeof === REACT_MEMO_TYPE ? console.error(
"forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."
) : "function" !== typeof render ? console.error(
"forwardRef requires a render function but was given %s.",
null === render ? "null" : typeof render
) : 0 !== render.length && 2 !== render.length && console.error(
"forwardRef render functions accept exactly two parameters: props and ref. %s",
1 === render.length ? "Did you forget to use the ref parameter?" : "Any additional parameter will be undefined."
);
null != render && null != render.defaultProps && console.error(
"forwardRef render functions do not support defaultProps. Did you accidentally pass a React component?"
);
var elementType = { $$typeof: REACT_FORWARD_REF_TYPE, render }, ownName;
Object.defineProperty(elementType, "displayName", {
enumerable: false,
configurable: true,
get: function() {
return ownName;
},
set: function(name) {
ownName = name;
render.name || render.displayName || (Object.defineProperty(render, "name", { value: name }), render.displayName = name);
}
});
return elementType;
};
exports.isValidElement = isValidElement;
exports.lazy = function(ctor) {
return {
$$typeof: REACT_LAZY_TYPE,
_payload: { _status: -1, _result: ctor },
_init: lazyInitializer
};
};
exports.memo = function(type, compare) {
null == type && console.error(
"memo: The first argument must be a component. Instead received: %s",
null === type ? "null" : typeof type
);
compare = {
$$typeof: REACT_MEMO_TYPE,
type,
compare: void 0 === compare ? null : compare
};
var ownName;
Object.defineProperty(compare, "displayName", {
enumerable: false,
configurable: true,
get: function() {
return ownName;
},
set: function(name) {
ownName = name;
type.name || type.displayName || (Object.defineProperty(type, "name", { value: name }), type.displayName = name);
}
});
return compare;
};
exports.startTransition = function(scope) {
var prevTransition = ReactSharedInternals.T, currentTransition = {};
ReactSharedInternals.T = currentTransition;
currentTransition._updatedFibers = /* @__PURE__ */ new Set();
try {
var returnValue = scope(), onStartTransitionFinish = ReactSharedInternals.S;
null !== onStartTransitionFinish && onStartTransitionFinish(currentTransition, returnValue);
"object" === typeof returnValue && null !== returnValue && "function" === typeof returnValue.then && returnValue.then(noop, reportGlobalError);
} catch (error) {
reportGlobalError(error);
} finally {
null === prevTransition && currentTransition._updatedFibers && (scope = currentTransition._updatedFibers.size, currentTransition._updatedFibers.clear(), 10 < scope && console.warn(
"Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table."
)), ReactSharedInternals.T = prevTransition;
}
};
exports.unstable_useCacheRefresh = function() {
return resolveDispatcher().useCacheRefresh();
};
exports.use = function(usable) {
return resolveDispatcher().use(usable);
};
exports.useActionState = function(action, initialState, permalink) {
return resolveDispatcher().useActionState(
action,
initialState,
permalink
);
};
exports.useCallback = function(callback, deps) {
return resolveDispatcher().useCallback(callback, deps);
};
exports.useContext = function(Context) {
var dispatcher = resolveDispatcher();
Context.$$typeof === REACT_CONSUMER_TYPE && console.error(
"Calling useContext(Context.Consumer) is not supported and will cause bugs. Did you mean to call useContext(Context) instead?"
);
return dispatcher.useContext(Context);
};
exports.useDebugValue = function(value, formatterFn) {
return resolveDispatcher().useDebugValue(value, formatterFn);
};
exports.useDeferredValue = function(value, initialValue) {
return resolveDispatcher().useDeferredValue(value, initialValue);
};
exports.useEffect = function(create, createDeps, update) {
null == create && console.warn(
"React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?"
);
var dispatcher = resolveDispatcher();
if ("function" === typeof update)
throw Error(
"useEffect CRUD overload is not enabled in this build of React."
);
return dispatcher.useEffect(create, createDeps);
};
exports.useId = function() {
return resolveDispatcher().useId();
};
exports.useImperativeHandle = function(ref, create, deps) {
return resolveDispatcher().useImperativeHandle(ref, create, deps);
};
exports.useInsertionEffect = function(create, deps) {
null == create && console.warn(
"React Hook useInsertionEffect requires an effect callback. Did you forget to pass a callback to the hook?"
);
return resolveDispatcher().useInsertionEffect(create, deps);
};
exports.useLayoutEffect = function(create, deps) {
null == create && console.warn(
"React Hook useLayoutEffect requires an effect callback. Did you forget to pass a callback to the hook?"
);
return resolveDispatcher().useLayoutEffect(create, deps);
};
exports.useMemo = function(create, deps) {
return resolveDispatcher().useMemo(create, deps);
};
exports.useOptimistic = function(passthrough, reducer) {
return resolveDispatcher().useOptimistic(passthrough, reducer);
};
exports.useReducer = function(reducer, initialArg, init) {
return resolveDispatcher().useReducer(reducer, initialArg, init);
};
exports.useRef = function(initialValue) {
return resolveDispatcher().useRef(initialValue);
};
exports.useState = function(initialState) {
return resolveDispatcher().useState(initialState);
};
exports.useSyncExternalStore = function(subscribe, getSnapshot, getServerSnapshot) {
return resolveDispatcher().useSyncExternalStore(
subscribe,
getSnapshot,
getServerSnapshot
);
};
exports.useTransition = function() {
return resolveDispatcher().useTransition();
};
exports.version = "19.1.0";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
})();
}
});
// node_modules/react/index.js
var require_react = __commonJS({
"node_modules/react/index.js"(exports, module) {
if (false) {
module.exports = null;
} else {
module.exports = require_react_development();
}
}
});
export {
require_react
};
/*! Bundled license information:
react/cjs/react.development.js:
(**
* @license React
* react.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
*/
//# sourceMappingURL=chunk-KS2M7ZJI.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,312 @@
// node_modules/preact/dist/preact.module.js
var n;
var l;
var u;
var t;
var i;
var r;
var o;
var e;
var f;
var c;
var s;
var a;
var h;
var p = {};
var y = [];
var v = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
var w = Array.isArray;
function d(n2, l2) {
for (var u2 in l2) n2[u2] = l2[u2];
return n2;
}
function g(n2) {
n2 && n2.parentNode && n2.parentNode.removeChild(n2);
}
function _(l2, u2, t2) {
var i2, r2, o2, e2 = {};
for (o2 in u2) "key" == o2 ? i2 = u2[o2] : "ref" == o2 ? r2 = u2[o2] : e2[o2] = u2[o2];
if (arguments.length > 2 && (e2.children = arguments.length > 3 ? n.call(arguments, 2) : t2), "function" == typeof l2 && null != l2.defaultProps) for (o2 in l2.defaultProps) null == e2[o2] && (e2[o2] = l2.defaultProps[o2]);
return m(l2, e2, i2, r2, null);
}
function m(n2, t2, i2, r2, o2) {
var e2 = { type: n2, props: t2, key: i2, ref: r2, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o2 ? ++u : o2, __i: -1, __u: 0 };
return null == o2 && null != l.vnode && l.vnode(e2), e2;
}
function b() {
return { current: null };
}
function k(n2) {
return n2.children;
}
function x(n2, l2) {
this.props = n2, this.context = l2;
}
function S(n2, l2) {
if (null == l2) return n2.__ ? S(n2.__, n2.__i + 1) : null;
for (var u2; l2 < n2.__k.length; l2++) if (null != (u2 = n2.__k[l2]) && null != u2.__e) return u2.__e;
return "function" == typeof n2.type ? S(n2) : null;
}
function C(n2) {
var l2, u2;
if (null != (n2 = n2.__) && null != n2.__c) {
for (n2.__e = n2.__c.base = null, l2 = 0; l2 < n2.__k.length; l2++) if (null != (u2 = n2.__k[l2]) && null != u2.__e) {
n2.__e = n2.__c.base = u2.__e;
break;
}
return C(n2);
}
}
function M(n2) {
(!n2.__d && (n2.__d = true) && i.push(n2) && !$.__r++ || r != l.debounceRendering) && ((r = l.debounceRendering) || o)($);
}
function $() {
for (var n2, u2, t2, r2, o2, f2, c2, s2 = 1; i.length; ) i.length > s2 && i.sort(e), n2 = i.shift(), s2 = i.length, n2.__d && (t2 = void 0, o2 = (r2 = (u2 = n2).__v).__e, f2 = [], c2 = [], u2.__P && ((t2 = d({}, r2)).__v = r2.__v + 1, l.vnode && l.vnode(t2), O(u2.__P, t2, r2, u2.__n, u2.__P.namespaceURI, 32 & r2.__u ? [o2] : null, f2, null == o2 ? S(r2) : o2, !!(32 & r2.__u), c2), t2.__v = r2.__v, t2.__.__k[t2.__i] = t2, z(f2, t2, c2), t2.__e != o2 && C(t2)));
$.__r = 0;
}
function I(n2, l2, u2, t2, i2, r2, o2, e2, f2, c2, s2) {
var a2, h2, v2, w2, d2, g2, _2 = t2 && t2.__k || y, m2 = l2.length;
for (f2 = P(u2, l2, _2, f2, m2), a2 = 0; a2 < m2; a2++) null != (v2 = u2.__k[a2]) && (h2 = -1 == v2.__i ? p : _2[v2.__i] || p, v2.__i = a2, g2 = O(n2, v2, h2, i2, r2, o2, e2, f2, c2, s2), w2 = v2.__e, v2.ref && h2.ref != v2.ref && (h2.ref && q(h2.ref, null, v2), s2.push(v2.ref, v2.__c || w2, v2)), null == d2 && null != w2 && (d2 = w2), 4 & v2.__u || h2.__k === v2.__k ? f2 = A(v2, f2, n2) : "function" == typeof v2.type && void 0 !== g2 ? f2 = g2 : w2 && (f2 = w2.nextSibling), v2.__u &= -7);
return u2.__e = d2, f2;
}
function P(n2, l2, u2, t2, i2) {
var r2, o2, e2, f2, c2, s2 = u2.length, a2 = s2, h2 = 0;
for (n2.__k = new Array(i2), r2 = 0; r2 < i2; r2++) null != (o2 = l2[r2]) && "boolean" != typeof o2 && "function" != typeof o2 ? (f2 = r2 + h2, (o2 = n2.__k[r2] = "string" == typeof o2 || "number" == typeof o2 || "bigint" == typeof o2 || o2.constructor == String ? m(null, o2, null, null, null) : w(o2) ? m(k, { children: o2 }, null, null, null) : null == o2.constructor && o2.__b > 0 ? m(o2.type, o2.props, o2.key, o2.ref ? o2.ref : null, o2.__v) : o2).__ = n2, o2.__b = n2.__b + 1, e2 = null, -1 != (c2 = o2.__i = L(o2, u2, f2, a2)) && (a2--, (e2 = u2[c2]) && (e2.__u |= 2)), null == e2 || null == e2.__v ? (-1 == c2 && (i2 > s2 ? h2-- : i2 < s2 && h2++), "function" != typeof o2.type && (o2.__u |= 4)) : c2 != f2 && (c2 == f2 - 1 ? h2-- : c2 == f2 + 1 ? h2++ : (c2 > f2 ? h2-- : h2++, o2.__u |= 4))) : n2.__k[r2] = null;
if (a2) for (r2 = 0; r2 < s2; r2++) null != (e2 = u2[r2]) && 0 == (2 & e2.__u) && (e2.__e == t2 && (t2 = S(e2)), B(e2, e2));
return t2;
}
function A(n2, l2, u2) {
var t2, i2;
if ("function" == typeof n2.type) {
for (t2 = n2.__k, i2 = 0; t2 && i2 < t2.length; i2++) t2[i2] && (t2[i2].__ = n2, l2 = A(t2[i2], l2, u2));
return l2;
}
n2.__e != l2 && (l2 && n2.type && !u2.contains(l2) && (l2 = S(n2)), u2.insertBefore(n2.__e, l2 || null), l2 = n2.__e);
do {
l2 = l2 && l2.nextSibling;
} while (null != l2 && 8 == l2.nodeType);
return l2;
}
function H(n2, l2) {
return l2 = l2 || [], null == n2 || "boolean" == typeof n2 || (w(n2) ? n2.some(function(n3) {
H(n3, l2);
}) : l2.push(n2)), l2;
}
function L(n2, l2, u2, t2) {
var i2, r2, o2 = n2.key, e2 = n2.type, f2 = l2[u2];
if (null === f2 && null == n2.key || f2 && o2 == f2.key && e2 == f2.type && 0 == (2 & f2.__u)) return u2;
if (t2 > (null != f2 && 0 == (2 & f2.__u) ? 1 : 0)) for (i2 = u2 - 1, r2 = u2 + 1; i2 >= 0 || r2 < l2.length; ) {
if (i2 >= 0) {
if ((f2 = l2[i2]) && 0 == (2 & f2.__u) && o2 == f2.key && e2 == f2.type) return i2;
i2--;
}
if (r2 < l2.length) {
if ((f2 = l2[r2]) && 0 == (2 & f2.__u) && o2 == f2.key && e2 == f2.type) return r2;
r2++;
}
}
return -1;
}
function T(n2, l2, u2) {
"-" == l2[0] ? n2.setProperty(l2, null == u2 ? "" : u2) : n2[l2] = null == u2 ? "" : "number" != typeof u2 || v.test(l2) ? u2 : u2 + "px";
}
function j(n2, l2, u2, t2, i2) {
var r2;
n: if ("style" == l2) if ("string" == typeof u2) n2.style.cssText = u2;
else {
if ("string" == typeof t2 && (n2.style.cssText = t2 = ""), t2) for (l2 in t2) u2 && l2 in u2 || T(n2.style, l2, "");
if (u2) for (l2 in u2) t2 && u2[l2] == t2[l2] || T(n2.style, l2, u2[l2]);
}
else if ("o" == l2[0] && "n" == l2[1]) r2 = l2 != (l2 = l2.replace(f, "$1")), l2 = l2.toLowerCase() in n2 || "onFocusOut" == l2 || "onFocusIn" == l2 ? l2.toLowerCase().slice(2) : l2.slice(2), n2.l || (n2.l = {}), n2.l[l2 + r2] = u2, u2 ? t2 ? u2.u = t2.u : (u2.u = c, n2.addEventListener(l2, r2 ? a : s, r2)) : n2.removeEventListener(l2, r2 ? a : s, r2);
else {
if ("http://www.w3.org/2000/svg" == i2) l2 = l2.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
else if ("width" != l2 && "height" != l2 && "href" != l2 && "list" != l2 && "form" != l2 && "tabIndex" != l2 && "download" != l2 && "rowSpan" != l2 && "colSpan" != l2 && "role" != l2 && "popover" != l2 && l2 in n2) try {
n2[l2] = null == u2 ? "" : u2;
break n;
} catch (n3) {
}
"function" == typeof u2 || (null == u2 || false === u2 && "-" != l2[4] ? n2.removeAttribute(l2) : n2.setAttribute(l2, "popover" == l2 && 1 == u2 ? "" : u2));
}
}
function F(n2) {
return function(u2) {
if (this.l) {
var t2 = this.l[u2.type + n2];
if (null == u2.t) u2.t = c++;
else if (u2.t < t2.u) return;
return t2(l.event ? l.event(u2) : u2);
}
};
}
function O(n2, u2, t2, i2, r2, o2, e2, f2, c2, s2) {
var a2, h2, p2, y2, v2, _2, m2, b2, S2, C2, M2, $2, P2, A2, H2, L2, T2, j2 = u2.type;
if (null != u2.constructor) return null;
128 & t2.__u && (c2 = !!(32 & t2.__u), o2 = [f2 = u2.__e = t2.__e]), (a2 = l.__b) && a2(u2);
n: if ("function" == typeof j2) try {
if (b2 = u2.props, S2 = "prototype" in j2 && j2.prototype.render, C2 = (a2 = j2.contextType) && i2[a2.__c], M2 = a2 ? C2 ? C2.props.value : a2.__ : i2, t2.__c ? m2 = (h2 = u2.__c = t2.__c).__ = h2.__E : (S2 ? u2.__c = h2 = new j2(b2, M2) : (u2.__c = h2 = new x(b2, M2), h2.constructor = j2, h2.render = D), C2 && C2.sub(h2), h2.props = b2, h2.state || (h2.state = {}), h2.context = M2, h2.__n = i2, p2 = h2.__d = true, h2.__h = [], h2._sb = []), S2 && null == h2.__s && (h2.__s = h2.state), S2 && null != j2.getDerivedStateFromProps && (h2.__s == h2.state && (h2.__s = d({}, h2.__s)), d(h2.__s, j2.getDerivedStateFromProps(b2, h2.__s))), y2 = h2.props, v2 = h2.state, h2.__v = u2, p2) S2 && null == j2.getDerivedStateFromProps && null != h2.componentWillMount && h2.componentWillMount(), S2 && null != h2.componentDidMount && h2.__h.push(h2.componentDidMount);
else {
if (S2 && null == j2.getDerivedStateFromProps && b2 !== y2 && null != h2.componentWillReceiveProps && h2.componentWillReceiveProps(b2, M2), !h2.__e && null != h2.shouldComponentUpdate && false === h2.shouldComponentUpdate(b2, h2.__s, M2) || u2.__v == t2.__v) {
for (u2.__v != t2.__v && (h2.props = b2, h2.state = h2.__s, h2.__d = false), u2.__e = t2.__e, u2.__k = t2.__k, u2.__k.some(function(n3) {
n3 && (n3.__ = u2);
}), $2 = 0; $2 < h2._sb.length; $2++) h2.__h.push(h2._sb[$2]);
h2._sb = [], h2.__h.length && e2.push(h2);
break n;
}
null != h2.componentWillUpdate && h2.componentWillUpdate(b2, h2.__s, M2), S2 && null != h2.componentDidUpdate && h2.__h.push(function() {
h2.componentDidUpdate(y2, v2, _2);
});
}
if (h2.context = M2, h2.props = b2, h2.__P = n2, h2.__e = false, P2 = l.__r, A2 = 0, S2) {
for (h2.state = h2.__s, h2.__d = false, P2 && P2(u2), a2 = h2.render(h2.props, h2.state, h2.context), H2 = 0; H2 < h2._sb.length; H2++) h2.__h.push(h2._sb[H2]);
h2._sb = [];
} else do {
h2.__d = false, P2 && P2(u2), a2 = h2.render(h2.props, h2.state, h2.context), h2.state = h2.__s;
} while (h2.__d && ++A2 < 25);
h2.state = h2.__s, null != h2.getChildContext && (i2 = d(d({}, i2), h2.getChildContext())), S2 && !p2 && null != h2.getSnapshotBeforeUpdate && (_2 = h2.getSnapshotBeforeUpdate(y2, v2)), L2 = a2, null != a2 && a2.type === k && null == a2.key && (L2 = N(a2.props.children)), f2 = I(n2, w(L2) ? L2 : [L2], u2, t2, i2, r2, o2, e2, f2, c2, s2), h2.base = u2.__e, u2.__u &= -161, h2.__h.length && e2.push(h2), m2 && (h2.__E = h2.__ = null);
} catch (n3) {
if (u2.__v = null, c2 || null != o2) if (n3.then) {
for (u2.__u |= c2 ? 160 : 128; f2 && 8 == f2.nodeType && f2.nextSibling; ) f2 = f2.nextSibling;
o2[o2.indexOf(f2)] = null, u2.__e = f2;
} else for (T2 = o2.length; T2--; ) g(o2[T2]);
else u2.__e = t2.__e, u2.__k = t2.__k;
l.__e(n3, u2, t2);
}
else null == o2 && u2.__v == t2.__v ? (u2.__k = t2.__k, u2.__e = t2.__e) : f2 = u2.__e = V(t2.__e, u2, t2, i2, r2, o2, e2, c2, s2);
return (a2 = l.diffed) && a2(u2), 128 & u2.__u ? void 0 : f2;
}
function z(n2, u2, t2) {
for (var i2 = 0; i2 < t2.length; i2++) q(t2[i2], t2[++i2], t2[++i2]);
l.__c && l.__c(u2, n2), n2.some(function(u3) {
try {
n2 = u3.__h, u3.__h = [], n2.some(function(n3) {
n3.call(u3);
});
} catch (n3) {
l.__e(n3, u3.__v);
}
});
}
function N(n2) {
return "object" != typeof n2 || null == n2 || n2.__b && n2.__b > 0 ? n2 : w(n2) ? n2.map(N) : d({}, n2);
}
function V(u2, t2, i2, r2, o2, e2, f2, c2, s2) {
var a2, h2, y2, v2, d2, _2, m2, b2 = i2.props, k2 = t2.props, x2 = t2.type;
if ("svg" == x2 ? o2 = "http://www.w3.org/2000/svg" : "math" == x2 ? o2 = "http://www.w3.org/1998/Math/MathML" : o2 || (o2 = "http://www.w3.org/1999/xhtml"), null != e2) {
for (a2 = 0; a2 < e2.length; a2++) if ((d2 = e2[a2]) && "setAttribute" in d2 == !!x2 && (x2 ? d2.localName == x2 : 3 == d2.nodeType)) {
u2 = d2, e2[a2] = null;
break;
}
}
if (null == u2) {
if (null == x2) return document.createTextNode(k2);
u2 = document.createElementNS(o2, x2, k2.is && k2), c2 && (l.__m && l.__m(t2, e2), c2 = false), e2 = null;
}
if (null == x2) b2 === k2 || c2 && u2.data == k2 || (u2.data = k2);
else {
if (e2 = e2 && n.call(u2.childNodes), b2 = i2.props || p, !c2 && null != e2) for (b2 = {}, a2 = 0; a2 < u2.attributes.length; a2++) b2[(d2 = u2.attributes[a2]).name] = d2.value;
for (a2 in b2) if (d2 = b2[a2], "children" == a2) ;
else if ("dangerouslySetInnerHTML" == a2) y2 = d2;
else if (!(a2 in k2)) {
if ("value" == a2 && "defaultValue" in k2 || "checked" == a2 && "defaultChecked" in k2) continue;
j(u2, a2, null, d2, o2);
}
for (a2 in k2) d2 = k2[a2], "children" == a2 ? v2 = d2 : "dangerouslySetInnerHTML" == a2 ? h2 = d2 : "value" == a2 ? _2 = d2 : "checked" == a2 ? m2 = d2 : c2 && "function" != typeof d2 || b2[a2] === d2 || j(u2, a2, d2, b2[a2], o2);
if (h2) c2 || y2 && (h2.__html == y2.__html || h2.__html == u2.innerHTML) || (u2.innerHTML = h2.__html), t2.__k = [];
else if (y2 && (u2.innerHTML = ""), I("template" == t2.type ? u2.content : u2, w(v2) ? v2 : [v2], t2, i2, r2, "foreignObject" == x2 ? "http://www.w3.org/1999/xhtml" : o2, e2, f2, e2 ? e2[0] : i2.__k && S(i2, 0), c2, s2), null != e2) for (a2 = e2.length; a2--; ) g(e2[a2]);
c2 || (a2 = "value", "progress" == x2 && null == _2 ? u2.removeAttribute("value") : null != _2 && (_2 !== u2[a2] || "progress" == x2 && !_2 || "option" == x2 && _2 != b2[a2]) && j(u2, a2, _2, b2[a2], o2), a2 = "checked", null != m2 && m2 != u2[a2] && j(u2, a2, m2, b2[a2], o2));
}
return u2;
}
function q(n2, u2, t2) {
try {
if ("function" == typeof n2) {
var i2 = "function" == typeof n2.__u;
i2 && n2.__u(), i2 && null == u2 || (n2.__u = n2(u2));
} else n2.current = u2;
} catch (n3) {
l.__e(n3, t2);
}
}
function B(n2, u2, t2) {
var i2, r2;
if (l.unmount && l.unmount(n2), (i2 = n2.ref) && (i2.current && i2.current != n2.__e || q(i2, null, u2)), null != (i2 = n2.__c)) {
if (i2.componentWillUnmount) try {
i2.componentWillUnmount();
} catch (n3) {
l.__e(n3, u2);
}
i2.base = i2.__P = null;
}
if (i2 = n2.__k) for (r2 = 0; r2 < i2.length; r2++) i2[r2] && B(i2[r2], u2, t2 || "function" != typeof n2.type);
t2 || g(n2.__e), n2.__c = n2.__ = n2.__e = void 0;
}
function D(n2, l2, u2) {
return this.constructor(n2, u2);
}
function E(u2, t2, i2) {
var r2, o2, e2, f2;
t2 == document && (t2 = document.documentElement), l.__ && l.__(u2, t2), o2 = (r2 = "function" == typeof i2) ? null : i2 && i2.__k || t2.__k, e2 = [], f2 = [], O(t2, u2 = (!r2 && i2 || t2).__k = _(k, null, [u2]), o2 || p, p, t2.namespaceURI, !r2 && i2 ? [i2] : o2 ? null : t2.firstChild ? n.call(t2.childNodes) : null, e2, !r2 && i2 ? i2 : o2 ? o2.__e : t2.firstChild, r2, f2), z(e2, u2, f2);
}
function G(n2, l2) {
E(n2, l2, G);
}
function J(l2, u2, t2) {
var i2, r2, o2, e2, f2 = d({}, l2.props);
for (o2 in l2.type && l2.type.defaultProps && (e2 = l2.type.defaultProps), u2) "key" == o2 ? i2 = u2[o2] : "ref" == o2 ? r2 = u2[o2] : f2[o2] = null == u2[o2] && null != e2 ? e2[o2] : u2[o2];
return arguments.length > 2 && (f2.children = arguments.length > 3 ? n.call(arguments, 2) : t2), m(l2.type, f2, i2 || l2.key, r2 || l2.ref, null);
}
function K(n2) {
function l2(n3) {
var u2, t2;
return this.getChildContext || (u2 = /* @__PURE__ */ new Set(), (t2 = {})[l2.__c] = this, this.getChildContext = function() {
return t2;
}, this.componentWillUnmount = function() {
u2 = null;
}, this.shouldComponentUpdate = function(n4) {
this.props.value != n4.value && u2.forEach(function(n5) {
n5.__e = true, M(n5);
});
}, this.sub = function(n4) {
u2.add(n4);
var l3 = n4.componentWillUnmount;
n4.componentWillUnmount = function() {
u2 && u2.delete(n4), l3 && l3.call(n4);
};
}), n3.children;
}
return l2.__c = "__cC" + h++, l2.__ = n2, l2.Provider = l2.__l = (l2.Consumer = function(n3, l3) {
return n3.children(l3);
}).contextType = l2, l2;
}
n = y.slice, l = { __e: function(n2, l2, u2, t2) {
for (var i2, r2, o2; l2 = l2.__; ) if ((i2 = l2.__c) && !i2.__) try {
if ((r2 = i2.constructor) && null != r2.getDerivedStateFromError && (i2.setState(r2.getDerivedStateFromError(n2)), o2 = i2.__d), null != i2.componentDidCatch && (i2.componentDidCatch(n2, t2 || {}), o2 = i2.__d), o2) return i2.__E = i2;
} catch (l3) {
n2 = l3;
}
throw n2;
} }, u = 0, t = function(n2) {
return null != n2 && null == n2.constructor;
}, x.prototype.setState = function(n2, l2) {
var u2;
u2 = null != this.__s && this.__s != this.state ? this.__s : this.__s = d({}, this.state), "function" == typeof n2 && (n2 = n2(d({}, u2), this.props)), n2 && d(u2, n2), null != n2 && this.__v && (l2 && this._sb.push(l2), M(this));
}, x.prototype.forceUpdate = function(n2) {
this.__v && (this.__e = true, n2 && this.__h.push(n2), M(this));
}, x.prototype.render = k, i = [], o = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e = function(n2, l2) {
return n2.__v.__b - l2.__v.__b;
}, $.__r = 0, f = /(PointerCapture)$|Capture$/i, c = 0, s = F(false), a = F(true), h = 0;
export {
l,
t,
_,
b,
k,
x,
H,
E,
G,
J,
K
};
//# sourceMappingURL=chunk-WFLWNDNR.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,493 @@
// node_modules/swiper/shared/ssr-window.esm.mjs
function isObject(obj) {
return obj !== null && typeof obj === "object" && "constructor" in obj && obj.constructor === Object;
}
function extend(target, src) {
if (target === void 0) {
target = {};
}
if (src === void 0) {
src = {};
}
const noExtend = ["__proto__", "constructor", "prototype"];
Object.keys(src).filter((key) => noExtend.indexOf(key) < 0).forEach((key) => {
if (typeof target[key] === "undefined") target[key] = src[key];
else if (isObject(src[key]) && isObject(target[key]) && Object.keys(src[key]).length > 0) {
extend(target[key], src[key]);
}
});
}
var ssrDocument = {
body: {},
addEventListener() {
},
removeEventListener() {
},
activeElement: {
blur() {
},
nodeName: ""
},
querySelector() {
return null;
},
querySelectorAll() {
return [];
},
getElementById() {
return null;
},
createEvent() {
return {
initEvent() {
}
};
},
createElement() {
return {
children: [],
childNodes: [],
style: {},
setAttribute() {
},
getElementsByTagName() {
return [];
}
};
},
createElementNS() {
return {};
},
importNode() {
return null;
},
location: {
hash: "",
host: "",
hostname: "",
href: "",
origin: "",
pathname: "",
protocol: "",
search: ""
}
};
function getDocument() {
const doc = typeof document !== "undefined" ? document : {};
extend(doc, ssrDocument);
return doc;
}
var ssrWindow = {
document: ssrDocument,
navigator: {
userAgent: ""
},
location: {
hash: "",
host: "",
hostname: "",
href: "",
origin: "",
pathname: "",
protocol: "",
search: ""
},
history: {
replaceState() {
},
pushState() {
},
go() {
},
back() {
}
},
CustomEvent: function CustomEvent() {
return this;
},
addEventListener() {
},
removeEventListener() {
},
getComputedStyle() {
return {
getPropertyValue() {
return "";
}
};
},
Image() {
},
Date() {
},
screen: {},
setTimeout() {
},
clearTimeout() {
},
matchMedia() {
return {};
},
requestAnimationFrame(callback) {
if (typeof setTimeout === "undefined") {
callback();
return null;
}
return setTimeout(callback, 0);
},
cancelAnimationFrame(id) {
if (typeof setTimeout === "undefined") {
return;
}
clearTimeout(id);
}
};
function getWindow() {
const win = typeof window !== "undefined" ? window : {};
extend(win, ssrWindow);
return win;
}
// node_modules/swiper/shared/utils.mjs
function classesToTokens(classes) {
if (classes === void 0) {
classes = "";
}
return classes.trim().split(" ").filter((c) => !!c.trim());
}
function deleteProps(obj) {
const object = obj;
Object.keys(object).forEach((key) => {
try {
object[key] = null;
} catch (e) {
}
try {
delete object[key];
} catch (e) {
}
});
}
function nextTick(callback, delay) {
if (delay === void 0) {
delay = 0;
}
return setTimeout(callback, delay);
}
function now() {
return Date.now();
}
function getComputedStyle(el) {
const window2 = getWindow();
let style;
if (window2.getComputedStyle) {
style = window2.getComputedStyle(el, null);
}
if (!style && el.currentStyle) {
style = el.currentStyle;
}
if (!style) {
style = el.style;
}
return style;
}
function getTranslate(el, axis) {
if (axis === void 0) {
axis = "x";
}
const window2 = getWindow();
let matrix;
let curTransform;
let transformMatrix;
const curStyle = getComputedStyle(el);
if (window2.WebKitCSSMatrix) {
curTransform = curStyle.transform || curStyle.webkitTransform;
if (curTransform.split(",").length > 6) {
curTransform = curTransform.split(", ").map((a) => a.replace(",", ".")).join(", ");
}
transformMatrix = new window2.WebKitCSSMatrix(curTransform === "none" ? "" : curTransform);
} else {
transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue("transform").replace("translate(", "matrix(1, 0, 0, 1,");
matrix = transformMatrix.toString().split(",");
}
if (axis === "x") {
if (window2.WebKitCSSMatrix) curTransform = transformMatrix.m41;
else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
else curTransform = parseFloat(matrix[4]);
}
if (axis === "y") {
if (window2.WebKitCSSMatrix) curTransform = transformMatrix.m42;
else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
else curTransform = parseFloat(matrix[5]);
}
return curTransform || 0;
}
function isObject2(o) {
return typeof o === "object" && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === "Object";
}
function isNode(node) {
if (typeof window !== "undefined" && typeof window.HTMLElement !== "undefined") {
return node instanceof HTMLElement;
}
return node && (node.nodeType === 1 || node.nodeType === 11);
}
function extend2() {
const to = Object(arguments.length <= 0 ? void 0 : arguments[0]);
const noExtend = ["__proto__", "constructor", "prototype"];
for (let i = 1; i < arguments.length; i += 1) {
const nextSource = i < 0 || arguments.length <= i ? void 0 : arguments[i];
if (nextSource !== void 0 && nextSource !== null && !isNode(nextSource)) {
const keysArray = Object.keys(Object(nextSource)).filter((key) => noExtend.indexOf(key) < 0);
for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
const nextKey = keysArray[nextIndex];
const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== void 0 && desc.enumerable) {
if (isObject2(to[nextKey]) && isObject2(nextSource[nextKey])) {
if (nextSource[nextKey].__swiper__) {
to[nextKey] = nextSource[nextKey];
} else {
extend2(to[nextKey], nextSource[nextKey]);
}
} else if (!isObject2(to[nextKey]) && isObject2(nextSource[nextKey])) {
to[nextKey] = {};
if (nextSource[nextKey].__swiper__) {
to[nextKey] = nextSource[nextKey];
} else {
extend2(to[nextKey], nextSource[nextKey]);
}
} else {
to[nextKey] = nextSource[nextKey];
}
}
}
}
}
return to;
}
function setCSSProperty(el, varName, varValue) {
el.style.setProperty(varName, varValue);
}
function animateCSSModeScroll(_ref) {
let {
swiper,
targetPosition,
side
} = _ref;
const window2 = getWindow();
const startPosition = -swiper.translate;
let startTime = null;
let time;
const duration = swiper.params.speed;
swiper.wrapperEl.style.scrollSnapType = "none";
window2.cancelAnimationFrame(swiper.cssModeFrameID);
const dir = targetPosition > startPosition ? "next" : "prev";
const isOutOfBound = (current, target) => {
return dir === "next" && current >= target || dir === "prev" && current <= target;
};
const animate = () => {
time = (/* @__PURE__ */ new Date()).getTime();
if (startTime === null) {
startTime = time;
}
const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
if (isOutOfBound(currentPosition, targetPosition)) {
currentPosition = targetPosition;
}
swiper.wrapperEl.scrollTo({
[side]: currentPosition
});
if (isOutOfBound(currentPosition, targetPosition)) {
swiper.wrapperEl.style.overflow = "hidden";
swiper.wrapperEl.style.scrollSnapType = "";
setTimeout(() => {
swiper.wrapperEl.style.overflow = "";
swiper.wrapperEl.scrollTo({
[side]: currentPosition
});
});
window2.cancelAnimationFrame(swiper.cssModeFrameID);
return;
}
swiper.cssModeFrameID = window2.requestAnimationFrame(animate);
};
animate();
}
function getSlideTransformEl(slideEl) {
return slideEl.querySelector(".swiper-slide-transform") || slideEl.shadowRoot && slideEl.shadowRoot.querySelector(".swiper-slide-transform") || slideEl;
}
function elementChildren(element, selector) {
if (selector === void 0) {
selector = "";
}
const window2 = getWindow();
const children = [...element.children];
if (window2.HTMLSlotElement && element instanceof HTMLSlotElement) {
children.push(...element.assignedElements());
}
if (!selector) {
return children;
}
return children.filter((el) => el.matches(selector));
}
function elementIsChildOfSlot(el, slot) {
const elementsQueue = [slot];
while (elementsQueue.length > 0) {
const elementToCheck = elementsQueue.shift();
if (el === elementToCheck) {
return true;
}
elementsQueue.push(...elementToCheck.children, ...elementToCheck.shadowRoot ? elementToCheck.shadowRoot.children : [], ...elementToCheck.assignedElements ? elementToCheck.assignedElements() : []);
}
}
function elementIsChildOf(el, parent) {
const window2 = getWindow();
let isChild = parent.contains(el);
if (!isChild && window2.HTMLSlotElement && parent instanceof HTMLSlotElement) {
const children = [...parent.assignedElements()];
isChild = children.includes(el);
if (!isChild) {
isChild = elementIsChildOfSlot(el, parent);
}
}
return isChild;
}
function showWarning(text) {
try {
console.warn(text);
return;
} catch (err) {
}
}
function createElement(tag, classes) {
if (classes === void 0) {
classes = [];
}
const el = document.createElement(tag);
el.classList.add(...Array.isArray(classes) ? classes : classesToTokens(classes));
return el;
}
function elementOffset(el) {
const window2 = getWindow();
const document2 = getDocument();
const box = el.getBoundingClientRect();
const body = document2.body;
const clientTop = el.clientTop || body.clientTop || 0;
const clientLeft = el.clientLeft || body.clientLeft || 0;
const scrollTop = el === window2 ? window2.scrollY : el.scrollTop;
const scrollLeft = el === window2 ? window2.scrollX : el.scrollLeft;
return {
top: box.top + scrollTop - clientTop,
left: box.left + scrollLeft - clientLeft
};
}
function elementPrevAll(el, selector) {
const prevEls = [];
while (el.previousElementSibling) {
const prev = el.previousElementSibling;
if (selector) {
if (prev.matches(selector)) prevEls.push(prev);
} else prevEls.push(prev);
el = prev;
}
return prevEls;
}
function elementNextAll(el, selector) {
const nextEls = [];
while (el.nextElementSibling) {
const next = el.nextElementSibling;
if (selector) {
if (next.matches(selector)) nextEls.push(next);
} else nextEls.push(next);
el = next;
}
return nextEls;
}
function elementStyle(el, prop) {
const window2 = getWindow();
return window2.getComputedStyle(el, null).getPropertyValue(prop);
}
function elementIndex(el) {
let child = el;
let i;
if (child) {
i = 0;
while ((child = child.previousSibling) !== null) {
if (child.nodeType === 1) i += 1;
}
return i;
}
return void 0;
}
function elementParents(el, selector) {
const parents = [];
let parent = el.parentElement;
while (parent) {
if (selector) {
if (parent.matches(selector)) parents.push(parent);
} else {
parents.push(parent);
}
parent = parent.parentElement;
}
return parents;
}
function elementTransitionEnd(el, callback) {
function fireCallBack(e) {
if (e.target !== el) return;
callback.call(el, e);
el.removeEventListener("transitionend", fireCallBack);
}
if (callback) {
el.addEventListener("transitionend", fireCallBack);
}
}
function elementOuterSize(el, size, includeMargins) {
const window2 = getWindow();
if (includeMargins) {
return el[size === "width" ? "offsetWidth" : "offsetHeight"] + parseFloat(window2.getComputedStyle(el, null).getPropertyValue(size === "width" ? "margin-right" : "margin-top")) + parseFloat(window2.getComputedStyle(el, null).getPropertyValue(size === "width" ? "margin-left" : "margin-bottom"));
}
return el.offsetWidth;
}
function makeElementsArray(el) {
return (Array.isArray(el) ? el : [el]).filter((e) => !!e);
}
function getRotateFix(swiper) {
return (v) => {
if (Math.abs(v) > 0 && swiper.browser && swiper.browser.need3dFix && Math.abs(v) % 90 === 0) {
return v + 1e-3;
}
return v;
};
}
export {
getDocument,
getWindow,
classesToTokens,
deleteProps,
nextTick,
now,
getTranslate,
isObject2 as isObject,
extend2 as extend,
setCSSProperty,
animateCSSModeScroll,
getSlideTransformEl,
elementChildren,
elementIsChildOf,
showWarning,
createElement,
elementOffset,
elementPrevAll,
elementNextAll,
elementStyle,
elementIndex,
elementParents,
elementTransitionEnd,
elementOuterSize,
makeElementsArray,
getRotateFix
};
//# sourceMappingURL=chunk-XLOWEJT4.js.map

File diff suppressed because one or more lines are too long

3
.vite/deps/package.json Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

430
.vite/deps/preact-iso.js Normal file
View File

@@ -0,0 +1,430 @@
import {
E,
G,
H,
J,
K,
_,
l
} from "./chunk-WFLWNDNR.js";
import "./chunk-5WRI5ZAA.js";
// node_modules/preact/hooks/dist/hooks.module.js
var t;
var r;
var u;
var i;
var o = 0;
var f = [];
var c = l;
var e = c.__b;
var a = c.__r;
var v = c.diffed;
var l2 = c.__c;
var m = c.unmount;
var s = c.__;
function p(n, t2) {
c.__h && c.__h(r, n, o || t2), o = 0;
var u2 = r.__H || (r.__H = { __: [], __h: [] });
return n >= u2.__.length && u2.__.push({}), u2.__[n];
}
function d(n) {
return o = 1, h(D, n);
}
function h(n, u2, i2) {
var o2 = p(t++, 2);
if (o2.t = n, !o2.__c && (o2.__ = [i2 ? i2(u2) : D(void 0, u2), function(n2) {
var t2 = o2.__N ? o2.__N[0] : o2.__[0], r2 = o2.t(t2, n2);
t2 !== r2 && (o2.__N = [r2, o2.__[1]], o2.__c.setState({}));
}], o2.__c = r, !r.__f)) {
var f2 = function(n2, t2, r2) {
if (!o2.__c.__H) return true;
var u3 = o2.__c.__H.__.filter(function(n3) {
return !!n3.__c;
});
if (u3.every(function(n3) {
return !n3.__N;
})) return !c2 || c2.call(this, n2, t2, r2);
var i3 = o2.__c.props !== n2;
return u3.forEach(function(n3) {
if (n3.__N) {
var t3 = n3.__[0];
n3.__ = n3.__N, n3.__N = void 0, t3 !== n3.__[0] && (i3 = true);
}
}), c2 && c2.call(this, n2, t2, r2) || i3;
};
r.__f = true;
var c2 = r.shouldComponentUpdate, e2 = r.componentWillUpdate;
r.componentWillUpdate = function(n2, t2, r2) {
if (this.__e) {
var u3 = c2;
c2 = void 0, f2(n2, t2, r2), c2 = u3;
}
e2 && e2.call(this, n2, t2, r2);
}, r.shouldComponentUpdate = f2;
}
return o2.__N || o2.__;
}
function _2(n, u2) {
var i2 = p(t++, 4);
!c.__s && C(i2.__H, u2) && (i2.__ = n, i2.u = u2, r.__h.push(i2));
}
function A(n) {
return o = 5, T(function() {
return { current: n };
}, []);
}
function T(n, r2) {
var u2 = p(t++, 7);
return C(u2.__H, r2) && (u2.__ = n(), u2.__H = r2, u2.__h = n), u2.__;
}
function x(n) {
var u2 = r.context[n.__c], i2 = p(t++, 9);
return i2.c = n, u2 ? (null == i2.__ && (i2.__ = true, u2.sub(r)), u2.props.value) : n.__;
}
function j() {
for (var n; n = f.shift(); ) if (n.__P && n.__H) try {
n.__H.__h.forEach(z), n.__H.__h.forEach(B), n.__H.__h = [];
} catch (t2) {
n.__H.__h = [], c.__e(t2, n.__v);
}
}
c.__b = function(n) {
r = null, e && e(n);
}, c.__ = function(n, t2) {
n && t2.__k && t2.__k.__m && (n.__m = t2.__k.__m), s && s(n, t2);
}, c.__r = function(n) {
a && a(n), t = 0;
var i2 = (r = n.__c).__H;
i2 && (u === r ? (i2.__h = [], r.__h = [], i2.__.forEach(function(n2) {
n2.__N && (n2.__ = n2.__N), n2.u = n2.__N = void 0;
})) : (i2.__h.forEach(z), i2.__h.forEach(B), i2.__h = [], t = 0)), u = r;
}, c.diffed = function(n) {
v && v(n);
var t2 = n.__c;
t2 && t2.__H && (t2.__H.__h.length && (1 !== f.push(t2) && i === c.requestAnimationFrame || ((i = c.requestAnimationFrame) || w)(j)), t2.__H.__.forEach(function(n2) {
n2.u && (n2.__H = n2.u), n2.u = void 0;
})), u = r = null;
}, c.__c = function(n, t2) {
t2.some(function(n2) {
try {
n2.__h.forEach(z), n2.__h = n2.__h.filter(function(n3) {
return !n3.__ || B(n3);
});
} catch (r2) {
t2.some(function(n3) {
n3.__h && (n3.__h = []);
}), t2 = [], c.__e(r2, n2.__v);
}
}), l2 && l2(n, t2);
}, c.unmount = function(n) {
m && m(n);
var t2, r2 = n.__c;
r2 && r2.__H && (r2.__H.__.forEach(function(n2) {
try {
z(n2);
} catch (n3) {
t2 = n3;
}
}), r2.__H = void 0, t2 && c.__e(t2, r2.__v));
};
var k = "function" == typeof requestAnimationFrame;
function w(n) {
var t2, r2 = function() {
clearTimeout(u2), k && cancelAnimationFrame(t2), setTimeout(n);
}, u2 = setTimeout(r2, 100);
k && (t2 = requestAnimationFrame(r2));
}
function z(n) {
var t2 = r, u2 = n.__c;
"function" == typeof u2 && (n.__c = void 0, u2()), r = t2;
}
function B(n) {
var t2 = r;
n.__c = n.__(), r = t2;
}
function C(n, t2) {
return !n || n.length !== t2.length || t2.some(function(t3, r2) {
return t3 !== n[r2];
});
}
function D(n, t2) {
return "function" == typeof t2 ? t2(n) : t2;
}
// node_modules/preact-iso/src/router.js
var push;
var scope;
var UPDATE = (state, url) => {
push = void 0;
if (url && url.type === "click") {
if (url.ctrlKey || url.metaKey || url.altKey || url.shiftKey || url.button !== 0) {
return state;
}
const link = url.target.closest("a[href]"), href = link && link.getAttribute("href");
if (!link || link.origin != location.origin || /^#/.test(href) || !/^(_?self)?$/i.test(link.target) || scope && (typeof scope == "string" ? !href.startsWith(scope) : !scope.test(href))) {
return state;
}
push = true;
url.preventDefault();
url = link.href.replace(location.origin, "");
} else if (typeof url === "string") {
push = true;
} else if (url && url.url) {
push = !url.replace;
url = url.url;
} else {
url = location.pathname + location.search;
}
if (push === true) history.pushState(null, "", url);
else if (push === false) history.replaceState(null, "", url);
return url;
};
var exec = (url, route, matches = {}) => {
url = url.split("/").filter(Boolean);
route = (route || "").split("/").filter(Boolean);
if (!matches.params) matches.params = {};
for (let i2 = 0, val, rest; i2 < Math.max(url.length, route.length); i2++) {
let [, m2, param, flag] = (route[i2] || "").match(/^(:?)(.*?)([+*?]?)$/);
val = url[i2];
if (!m2 && param == val) continue;
if (!m2 && val && flag == "*") {
matches.rest = "/" + url.slice(i2).map(decodeURIComponent).join("/");
break;
}
if (!m2 || !val && flag != "?" && flag != "*") return;
rest = flag == "+" || flag == "*";
if (rest) val = url.slice(i2).map(decodeURIComponent).join("/") || void 0;
else if (val) val = decodeURIComponent(val);
matches.params[param] = val;
if (!(param in matches)) matches[param] = val;
if (rest) break;
}
return matches;
};
function LocationProvider(props) {
const [url, route] = h(UPDATE, props.url || location.pathname + location.search);
if (props.scope) scope = props.scope;
const wasPush = push === true;
const value = T(() => {
const u2 = new URL(url, location.origin);
const path = u2.pathname.replace(/\/+$/g, "") || "/";
return {
url,
path,
query: Object.fromEntries(u2.searchParams),
route: (url2, replace) => route({ url: url2, replace }),
wasPush
};
}, [url]);
_2(() => {
addEventListener("click", route);
addEventListener("popstate", route);
return () => {
removeEventListener("click", route);
removeEventListener("popstate", route);
};
}, []);
return _(LocationProvider.ctx.Provider, { value }, props.children);
}
var RESOLVED = Promise.resolve();
function Router(props) {
const [c2, update] = h((c3) => c3 + 1, 0);
const { url, query, wasPush, path } = useLocation();
const { rest = path, params = {} } = x(RouteContext);
const isLoading = A(false);
const prevRoute = A(path);
const count = A(0);
const cur = (
/** @type {RefObject<VNode<any>>} */
A()
);
const prev = (
/** @type {RefObject<VNode<any>>} */
A()
);
const pendingBase = (
/** @type {RefObject<Element | Text>} */
A()
);
const hasEverCommitted = A(false);
const didSuspend = (
/** @type {RefObject<boolean>} */
A()
);
didSuspend.current = false;
let pathRoute, defaultRoute, matchProps;
H(props.children).some((vnode) => {
const matches = exec(rest, vnode.props.path, matchProps = { ...vnode.props, path: rest, query, params, rest: "" });
if (matches) return pathRoute = J(vnode, matchProps);
if (vnode.props.default) defaultRoute = J(vnode, matchProps);
});
let incoming = pathRoute || defaultRoute;
const isHydratingSuspense = cur.current && cur.current.__u & MODE_HYDRATE && cur.current.__u & MODE_SUSPENDED;
const isHydratingBool = cur.current && cur.current.__h;
const routeChanged = T(() => {
prev.current = cur.current;
cur.current = /** @type {VNode<any>} */
_(RouteContext.Provider, { value: matchProps }, incoming);
const outgoing = prev.current && prev.current.props.children;
if (!outgoing || !incoming || incoming.type !== outgoing.type || incoming.props.component !== outgoing.props.component) {
if (this.__v && this.__v.__k) this.__v.__k.reverse();
count.current++;
return true;
}
return false;
}, [url, JSON.stringify(matchProps)]);
if (isHydratingSuspense) {
cur.current.__u |= MODE_HYDRATE;
cur.current.__u |= MODE_SUSPENDED;
} else if (isHydratingBool) {
cur.current.__h = true;
}
const p2 = prev.current;
prev.current = null;
this.__c = (e2, suspendedVNode) => {
didSuspend.current = true;
prev.current = p2;
if (props.onLoadStart) props.onLoadStart(url);
isLoading.current = true;
let c3 = count.current;
e2.then(() => {
if (c3 !== count.current) return;
prev.current = null;
if (cur.current) {
if (suspendedVNode.__h) {
cur.current.__h = suspendedVNode.__h;
}
if (suspendedVNode.__u & MODE_SUSPENDED) {
cur.current.__u |= MODE_SUSPENDED;
}
if (suspendedVNode.__u & MODE_HYDRATE) {
cur.current.__u |= MODE_HYDRATE;
}
}
RESOLVED.then(update);
});
};
_2(() => {
const currentDom = this.__v && this.__v.__e;
if (didSuspend.current) {
if (!hasEverCommitted.current && !pendingBase.current) {
pendingBase.current = currentDom;
}
return;
}
if (!hasEverCommitted.current && pendingBase.current) {
if (pendingBase.current !== currentDom) pendingBase.current.remove();
pendingBase.current = null;
}
hasEverCommitted.current = true;
if (prevRoute.current !== path) {
if (wasPush) scrollTo(0, 0);
if (props.onRouteChange) props.onRouteChange(url);
prevRoute.current = path;
}
if (props.onLoadEnd && isLoading.current) props.onLoadEnd(url);
isLoading.current = false;
}, [path, wasPush, c2]);
return routeChanged ? [_(RenderRef, { r: cur }), _(RenderRef, { r: prev })] : _(RenderRef, { r: cur });
}
var MODE_HYDRATE = 1 << 5;
var MODE_SUSPENDED = 1 << 7;
var RenderRef = ({ r: r2 }) => r2.current;
Router.Provider = LocationProvider;
LocationProvider.ctx = K(
/** @type {import('./router.d.ts').LocationHook & { wasPush: boolean }} */
{}
);
var RouteContext = K(
/** @type {import('./router.d.ts').RouteHook & { rest: string }} */
{}
);
var Route = (props) => _(props.component, props);
var useLocation = () => x(LocationProvider.ctx);
var useRoute = () => x(RouteContext);
// node_modules/preact-iso/src/lazy.js
var oldDiff = l.__b;
l.__b = (vnode) => {
if (vnode.type && vnode.type._forwarded && vnode.ref) {
vnode.props.ref = vnode.ref;
vnode.ref = null;
}
if (oldDiff) oldDiff(vnode);
};
function lazy(load) {
let p2, c2;
const loadModule = () => load().then((m2) => c2 = m2 && m2.default || m2);
const LazyComponent = (props) => {
const [, update] = d(0);
const r2 = A(c2);
if (!p2) p2 = loadModule();
if (c2 !== void 0) return _(c2, props);
if (!r2.current) r2.current = p2.then(() => update(1));
throw p2;
};
LazyComponent.preload = () => {
if (!p2) p2 = loadModule();
return p2;
};
LazyComponent._forwarded = true;
return LazyComponent;
}
var oldCatchError = l.__e;
l.__e = (err, newVNode, oldVNode) => {
if (err && err.then) {
let v2 = newVNode;
while (v2 = v2.__) {
if (v2.__c && v2.__c.__c) {
if (newVNode.__e == null) {
newVNode.__c.__z = [oldVNode.__e];
newVNode.__e = oldVNode.__e;
newVNode.__k = oldVNode.__k;
}
if (!newVNode.__k) newVNode.__k = [];
return v2.__c.__c(err, newVNode);
}
}
}
if (oldCatchError) oldCatchError(err, newVNode, oldVNode);
};
function ErrorBoundary(props) {
this.__c = childDidSuspend;
this.componentDidCatch = props.onError;
return props.children;
}
function childDidSuspend(err) {
err.then(() => this.forceUpdate());
}
// node_modules/preact-iso/src/hydrate.js
var initialized;
function hydrate(jsx, parent) {
if (typeof window === "undefined") return;
let isodata = document.querySelector("script[type=isodata]");
parent = parent || isodata && isodata.parentNode || document.body;
if (!initialized && isodata) {
G(jsx, parent);
} else {
E(jsx, parent);
}
initialized = true;
}
// node_modules/preact-iso/src/index.js
function prerender(vnode, options) {
return import("./prerender-2A2BKSYN.js").then((m2) => m2.default(vnode, options));
}
export {
ErrorBoundary,
LocationProvider,
Route,
Router,
hydrate,
lazy,
prerender,
useLocation,
useRoute
};
//# sourceMappingURL=preact-iso.js.map

File diff suppressed because one or more lines are too long

28
.vite/deps/preact.js Normal file
View File

@@ -0,0 +1,28 @@
import {
E,
G,
H,
J,
K,
_,
b,
k,
l,
t,
x
} from "./chunk-WFLWNDNR.js";
import "./chunk-5WRI5ZAA.js";
export {
x as Component,
k as Fragment,
J as cloneElement,
K as createContext,
_ as createElement,
b as createRef,
_ as h,
G as hydrate,
t as isValidElement,
l as options,
E as render,
H as toChildArray
};

7
.vite/deps/preact.js.map Normal file
View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

View File

@@ -0,0 +1,392 @@
import {
J,
_,
k,
l
} from "./chunk-WFLWNDNR.js";
import "./chunk-5WRI5ZAA.js";
// node_modules/preact-render-to-string/dist/index.module.js
var n = /[\s\n\\/='"\0<>]/;
var o = /^(xlink|xmlns|xml)([A-Z])/;
var i = /^(?:accessK|auto[A-Z]|cell|ch|col|cont|cross|dateT|encT|form[A-Z]|frame|hrefL|inputM|maxL|minL|noV|playsI|popoverT|readO|rowS|src[A-Z]|tabI|useM|item[A-Z])/;
var a = /^ac|^ali|arabic|basel|cap|clipPath$|clipRule$|color|dominant|enable|fill|flood|font|glyph[^R]|horiz|image|letter|lighting|marker[^WUH]|overline|panose|pointe|paint|rendering|shape|stop|strikethrough|stroke|text[^L]|transform|underline|unicode|units|^v[^i]|^w|^xH/;
var c = /* @__PURE__ */ new Set(["draggable", "spellcheck"]);
var s = /["&<]/;
function l2(e) {
if (0 === e.length || false === s.test(e)) return e;
for (var t = 0, r = 0, n2 = "", o2 = ""; r < e.length; r++) {
switch (e.charCodeAt(r)) {
case 34:
o2 = "&quot;";
break;
case 38:
o2 = "&amp;";
break;
case 60:
o2 = "&lt;";
break;
default:
continue;
}
r !== t && (n2 += e.slice(t, r)), n2 += o2, t = r + 1;
}
return r !== t && (n2 += e.slice(t, r)), n2;
}
var u = {};
var f = /* @__PURE__ */ new Set(["animation-iteration-count", "border-image-outset", "border-image-slice", "border-image-width", "box-flex", "box-flex-group", "box-ordinal-group", "column-count", "fill-opacity", "flex", "flex-grow", "flex-negative", "flex-order", "flex-positive", "flex-shrink", "flood-opacity", "font-weight", "grid-column", "grid-row", "line-clamp", "line-height", "opacity", "order", "orphans", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-miterlimit", "stroke-opacity", "stroke-width", "tab-size", "widows", "z-index", "zoom"]);
var p = /[A-Z]/g;
function h(e) {
var t = "";
for (var r in e) {
var n2 = e[r];
if (null != n2 && "" !== n2) {
var o2 = "-" == r[0] ? r : u[r] || (u[r] = r.replace(p, "-$&").toLowerCase()), i2 = ";";
"number" != typeof n2 || o2.startsWith("--") || f.has(o2) || (i2 = "px;"), t = t + o2 + ":" + n2 + i2;
}
}
return t || void 0;
}
function d() {
this.__d = true;
}
function v(e, t) {
return { __v: e, context: t, props: e.props, setState: d, forceUpdate: d, __d: true, __h: new Array(0) };
}
function _2(e, t, r) {
if (!e.s) {
if (r instanceof m) {
if (!r.s) return void (r.o = _2.bind(null, e, t));
1 & t && (t = r.s), r = r.v;
}
if (r && r.then) return void r.then(_2.bind(null, e, t), _2.bind(null, e, 2));
e.s = t, e.v = r;
const n2 = e.o;
n2 && n2(e);
}
}
var m = function() {
function e() {
}
return e.prototype.then = function(t, r) {
var n2 = new e(), o2 = this.s;
if (o2) {
var i2 = 1 & o2 ? t : r;
if (i2) {
try {
_2(n2, 1, i2(this.v));
} catch (e2) {
_2(n2, 2, e2);
}
return n2;
}
return this;
}
return this.o = function(e2) {
try {
var o3 = e2.v;
1 & e2.s ? _2(n2, 1, t ? t(o3) : o3) : r ? _2(n2, 1, r(o3)) : _2(n2, 2, o3);
} catch (e3) {
_2(n2, 2, e3);
}
}, n2;
}, e;
}();
function y(e) {
return e instanceof m && 1 & e.s;
}
function g(e, t, r) {
for (var n2; ; ) {
var o2 = e();
if (y(o2) && (o2 = o2.v), !o2) return i2;
if (o2.then) {
n2 = 0;
break;
}
var i2 = r();
if (i2 && i2.then) {
if (!y(i2)) {
n2 = 1;
break;
}
i2 = i2.s;
}
if (t) {
var a2 = t();
if (a2 && a2.then && !y(a2)) {
n2 = 2;
break;
}
}
}
var c2 = new m(), s2 = _2.bind(null, c2, 2);
return (0 === n2 ? o2.then(u2) : 1 === n2 ? i2.then(l3) : a2.then(f2)).then(void 0, s2), c2;
function l3(n3) {
i2 = n3;
do {
if (t && (a2 = t()) && a2.then && !y(a2)) return void a2.then(f2).then(void 0, s2);
if (!(o2 = e()) || y(o2) && !o2.v) return void _2(c2, 1, i2);
if (o2.then) return void o2.then(u2).then(void 0, s2);
y(i2 = r()) && (i2 = i2.v);
} while (!i2 || !i2.then);
i2.then(l3).then(void 0, s2);
}
function u2(e2) {
e2 ? (i2 = r()) && i2.then ? i2.then(l3).then(void 0, s2) : l3(i2) : _2(c2, 1, i2);
}
function f2() {
(o2 = e()) ? o2.then ? o2.then(u2).then(void 0, s2) : u2(o2) : _2(c2, 1, i2);
}
}
function b(e, t) {
try {
var r = e();
} catch (e2) {
return t(true, e2);
}
return r && r.then ? r.then(t.bind(null, false), t.bind(null, true)) : t(false, r);
}
var k2;
var w;
var x;
var C;
var A = function(n2, o2) {
try {
var i2 = l.__s;
l.__s = true, k2 = l.__b, w = l.diffed, x = l.__r, C = l.unmount;
var a2 = _(k, null);
return a2.__k = [n2], Promise.resolve(b(function() {
return Promise.resolve(U(n2, o2 || S, false, void 0, a2, true, void 0)).then(function(e) {
var t, r = function() {
if (E(e)) {
var r2 = function() {
var e2 = o3.join(j);
return t = 1, e2;
}, n3 = 0, o3 = e, i3 = g(function() {
return !!o3.some(function(e2) {
return e2 && "function" == typeof e2.then;
}) && n3++ < 25;
}, void 0, function() {
return Promise.resolve(Promise.all(o3)).then(function(e2) {
o3 = e2.flat();
});
});
return i3 && i3.then ? i3.then(r2) : r2();
}
}();
return r && r.then ? r.then(function(r2) {
return t ? r2 : e;
}) : t ? r : e;
});
}, function(t, r) {
if (l.__c && l.__c(n2, L), l.__s = i2, L.length = 0, t) throw r;
return r;
}));
} catch (e) {
return Promise.reject(e);
}
};
var S = {};
var L = [];
var E = Array.isArray;
var T = Object.assign;
var j = "";
function P(e, t) {
var r, n2 = e.type, o2 = true;
return e.__c ? (o2 = false, (r = e.__c).state = r.__s) : r = new n2(e.props, t), e.__c = r, r.__v = e, r.props = e.props, r.context = t, r.__d = true, null == r.state && (r.state = S), null == r.__s && (r.__s = r.state), n2.getDerivedStateFromProps ? r.state = T({}, r.state, n2.getDerivedStateFromProps(r.props, r.state)) : o2 && r.componentWillMount ? (r.componentWillMount(), r.state = r.__s !== r.state ? r.__s : r.state) : !o2 && r.componentWillUpdate && r.componentWillUpdate(), x && x(e), r.render(r.props, r.state, t);
}
function U(t, s2, u2, f2, p2, d2, _3) {
if (null == t || true === t || false === t || t === j) return j;
var m2 = typeof t;
if ("object" != m2) return "function" == m2 ? j : "string" == m2 ? l2(t) : t + j;
if (E(t)) {
var y2, g2 = j;
p2.__k = t;
for (var b2 = t.length, A2 = 0; A2 < b2; A2++) {
var L2 = t[A2];
if (null != L2 && "boolean" != typeof L2) {
var D, F = U(L2, s2, u2, f2, p2, d2, _3);
"string" == typeof F ? g2 += F : (y2 || (y2 = new Array(b2)), g2 && y2.push(g2), g2 = j, E(F) ? (D = y2).push.apply(D, F) : y2.push(F));
}
}
return y2 ? (g2 && y2.push(g2), y2) : g2;
}
if (void 0 !== t.constructor) return j;
t.__ = p2, k2 && k2(t);
var M = t.type, W = t.props;
if ("function" == typeof M) {
var $, z, H, N = s2;
if (M === k) {
if ("tpl" in W) {
for (var q = j, B = 0; B < W.tpl.length; B++) if (q += W.tpl[B], W.exprs && B < W.exprs.length) {
var I = W.exprs[B];
if (null == I) continue;
"object" != typeof I || void 0 !== I.constructor && !E(I) ? q += I : q += U(I, s2, u2, f2, t, d2, _3);
}
return q;
}
if ("UNSTABLE_comment" in W) return "<!--" + l2(W.UNSTABLE_comment) + "-->";
z = W.children;
} else {
if (null != ($ = M.contextType)) {
var O = s2[$.__c];
N = O ? O.props.value : $.__;
}
var R = M.prototype && "function" == typeof M.prototype.render;
if (R) z = P(t, N), H = t.__c;
else {
t.__c = H = v(t, N);
for (var V = 0; H.__d && V++ < 25; ) H.__d = false, x && x(t), z = M.call(H, W, N);
H.__d = true;
}
if (null != H.getChildContext && (s2 = T({}, s2, H.getChildContext())), R && l.errorBoundaries && (M.getDerivedStateFromError || H.componentDidCatch)) {
z = null != z && z.type === k && null == z.key && null == z.props.tpl ? z.props.children : z;
try {
return U(z, s2, u2, f2, t, d2, _3);
} catch (e) {
return M.getDerivedStateFromError && (H.__s = M.getDerivedStateFromError(e)), H.componentDidCatch && H.componentDidCatch(e, S), H.__d ? (z = P(t, s2), null != (H = t.__c).getChildContext && (s2 = T({}, s2, H.getChildContext())), U(z = null != z && z.type === k && null == z.key && null == z.props.tpl ? z.props.children : z, s2, u2, f2, t, d2, _3)) : j;
} finally {
w && w(t), C && C(t);
}
}
}
z = null != z && z.type === k && null == z.key && null == z.props.tpl ? z.props.children : z;
try {
var K = U(z, s2, u2, f2, t, d2, _3);
return w && w(t), l.unmount && l.unmount(t), K;
} catch (r) {
if (!d2 && _3 && _3.onError) {
var G = _3.onError(r, t, function(e, t2) {
return U(e, s2, u2, f2, t2, d2, _3);
});
if (void 0 !== G) return G;
var J2 = l.__e;
return J2 && J2(r, t), j;
}
if (!d2) throw r;
if (!r || "function" != typeof r.then) throw r;
return r.then(function e() {
try {
return U(z, s2, u2, f2, t, d2, _3);
} catch (r2) {
if (!r2 || "function" != typeof r2.then) throw r2;
return r2.then(function() {
return U(z, s2, u2, f2, t, d2, _3);
}, e);
}
});
}
}
var Q, X = "<" + M, Y = j;
for (var ee in W) {
var te = W[ee];
if ("function" != typeof te || "class" === ee || "className" === ee) {
switch (ee) {
case "children":
Q = te;
continue;
case "key":
case "ref":
case "__self":
case "__source":
continue;
case "htmlFor":
if ("for" in W) continue;
ee = "for";
break;
case "className":
if ("class" in W) continue;
ee = "class";
break;
case "defaultChecked":
ee = "checked";
break;
case "defaultSelected":
ee = "selected";
break;
case "defaultValue":
case "value":
switch (ee = "value", M) {
case "textarea":
Q = te;
continue;
case "select":
f2 = te;
continue;
case "option":
f2 != te || "selected" in W || (X += " selected");
}
break;
case "dangerouslySetInnerHTML":
Y = te && te.__html;
continue;
case "style":
"object" == typeof te && (te = h(te));
break;
case "acceptCharset":
ee = "accept-charset";
break;
case "httpEquiv":
ee = "http-equiv";
break;
default:
if (o.test(ee)) ee = ee.replace(o, "$1:$2").toLowerCase();
else {
if (n.test(ee)) continue;
"-" !== ee[4] && !c.has(ee) || null == te ? u2 ? a.test(ee) && (ee = "panose1" === ee ? "panose-1" : ee.replace(/([A-Z])/g, "-$1").toLowerCase()) : i.test(ee) && (ee = ee.toLowerCase()) : te += j;
}
}
null != te && false !== te && (X = true === te || te === j ? X + " " + ee : X + " " + ee + '="' + ("string" == typeof te ? l2(te) : te + j) + '"');
}
}
if (n.test(M)) throw new Error(M + " is not a valid HTML tag name in " + X + ">");
if (Y || ("string" == typeof Q ? Y = l2(Q) : null != Q && false !== Q && true !== Q && (Y = U(Q, s2, "svg" === M || "foreignObject" !== M && u2, f2, t, d2, _3))), w && w(t), C && C(t), !Y && Z.has(M)) return X + "/>";
var re = "</" + M + ">", ne = X + ">";
return E(Y) ? [ne].concat(Y, [re]) : "string" != typeof Y ? [ne, Y, re] : ne + Y + re;
}
var Z = /* @__PURE__ */ new Set(["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"]);
// node_modules/preact-iso/src/prerender.js
var vnodeHook;
var old = l.vnode;
l.vnode = (vnode) => {
if (old) old(vnode);
if (vnodeHook) vnodeHook(vnode);
};
async function prerender(vnode, options) {
options = options || {};
const props = options.props;
if (typeof vnode === "function") {
vnode = _(vnode, props);
} else if (props) {
vnode = J(vnode, props);
}
let links = /* @__PURE__ */ new Set();
vnodeHook = ({ type, props: props2 }) => {
if (type === "a" && props2 && props2.href && (!props2.target || props2.target === "_self")) {
links.add(props2.href);
}
};
try {
let html = await A(vnode);
html += `<script type="isodata"><\/script>`;
return { html, links };
} finally {
vnodeHook = null;
}
}
function locationStub(path) {
globalThis.location = {};
const u2 = new URL(path, "http://localhost");
for (const i2 in u2) {
try {
globalThis.location[i2] = /to[A-Z]/.test(i2) ? u2[i2].bind(u2) : String(u2[i2]);
} catch {
}
}
}
export {
prerender as default,
locationStub
};
//# sourceMappingURL=prerender-2A2BKSYN.js.map

File diff suppressed because one or more lines are too long

5
.vite/deps/react.js vendored Normal file
View File

@@ -0,0 +1,5 @@
import {
require_react
} from "./chunk-KS2M7ZJI.js";
import "./chunk-5WRI5ZAA.js";
export default require_react();

7
.vite/deps/react.js.map Normal file
View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

5248
.vite/deps/swiper_modules.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

4561
.vite/deps/swiper_react.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -8,4 +8,133 @@ return [
'query' => [],
'url' => '/buildpc',
],
// product
"/danh-muc-cap1.html" => [
'module' => 'category',
'view' => 'home',
'view_id'=> 0,
'query' => [],
'url' => '/danh-muc-cap1.html',
],
"/danh-muc-cap2.html" => [
'module' => 'category',
'view' => 'detail',
'view_id'=> 0,
'query' => [],
'url' => '/danh-muc-cap2.html',
],
"/product-detail" => [
'module' => 'product',
'view' => 'detail',
'view_id'=> 0,
'query' => [],
'url' => '/product-detail',
],
// san pham da luu
"/san-pham-da-luu" => [
'module' => 'product',
'view' => 'productsave',
'view_id'=> 0,
'query' => [],
'url' => '/san-pham-da-luu',
],
// tim nguoi ban
"/tim-nguoi-ban" => [
'module' => 'shop',
'view' => 'home',
'view_id'=> 0,
'query' => [],
'url' => '/tim-nguoi-ban',
],
// địa chỉ sửa chữa
"/dia-chi-sua-chua" => [
'module' => 'repair',
'view' => 'home',
'view_id'=> 0,
'query' => [],
'url' => '/dia-chi-sua-chua',
],
// hoi dap
"/hoi-dap" => [
'module' => 'faq',
'view' => 'home',
'view_id'=> 0,
'query' => [],
'url' => '/hoi-dap',
],
"/question-form" => [
'module' => 'faq',
'view' => 'form',
'view_id'=> 0,
'query' => [],
'url' => '/question-form',
],
"/chi-tiet-cau-hoi-dap" => [
'module' => 'faq',
'view' => 'detail',
'view_id'=> 0,
'query' => [],
'url' => '/chi-tiet-cau-hoi-dap',
],
// tin rao vat
"/tin-rao-vat" => [
'module' => 'classifieds',
'view' => 'home',
'view_id'=> 0,
'query' => [],
'url' => '/tin-rao-vat',
],
"/san-pham-nguoi-ban" => [
'module' => 'classifieds',
'view' => 'detail',
'view_id'=> 0,
'query' => [],
'url' => '/san-pham-nguoi-ban',
],
// taikhoan
"/taikhoan" => [
'module' => 'account',
'view' => 'home',
'view_id'=> 0,
'query' => [
"view" => "info"
],
'url' => '/taikhoan?view=info',
],
"/taikhoan?view=question" => [
'module' => 'account',
'view' => 'home',
'view_id'=> 0,
'query' => [
"view" => "question"
],
'url' => '/taikhoan?view=question',
],
"/taikhoan?view=classifieds" => [
'module' => 'account',
'view' => 'layout',
'view_id'=> 0,
'query' => [
"view" => "classifieds"
],
'url' => '/taikhoan?view=classifieds',
],
"/taikhoan?view=inbox" => [
'module' => 'account',
'view' => 'layout',
'view_id'=> 0,
'query' => [
"view" => "inbox"
],
'url' => '/taikhoan?view=inbox',
],
"/taikhoan?view=info-save" => [
'module' => 'account',
'view' => 'layout',
'view_id'=> 0,
'query' => [
"view" => "product_save"
],
'url' => '/taikhoan?view=info-save',
],
];

View File

@@ -3,7 +3,6 @@ import { Swiper, SwiperSlide } from "swiper/react";
import { SupplierListBox } from "../../components/product/SupplierListBox";
import { ProductDescription } from "../../components/product/ProductDescription";
import { MemberReview } from "../../components/product/MemberReview";
import { ProductReview } from "../../components/product/ProductReview";
import { FreeMode, Navigation, Thumbs } from "swiper/modules";
@@ -249,8 +248,8 @@ export function ProductDetail() {
{/* đánh giá thành viên bestpc */}
<ProductReview />
{/* <ProductReview /> */}
{/* đánh giá trên internet */}
<ProductDescription />
{/* thông tin sản phẩm */}

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,7 @@
},
"devDependencies": {
"@preact/preset-vite": "^2.9.3",
"@types/node": "^22.15.23",
"eslint": "^8.57.1",
"eslint-config-preact": "^1.5.0",
"typescript": "^5.8.3",
@@ -1329,6 +1330,16 @@
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
"dev": true
},
"node_modules/@types/node": {
"version": "22.15.23",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.23.tgz",
"integrity": "sha512-7Ec1zaFPF4RJ0eXu1YT/xgiebqwqoJz8rYPDi/O2BcZ++Wpt0Kq9cl0eg6NN6bYbPnR67ZLo7St5Q3UK0SnARw==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/@ungap/structured-clone": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
@@ -4736,6 +4747,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
@@ -5825,6 +5843,15 @@
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
"dev": true
},
"@types/node": {
"version": "22.15.23",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.23.tgz",
"integrity": "sha512-7Ec1zaFPF4RJ0eXu1YT/xgiebqwqoJz8rYPDi/O2BcZ++Wpt0Kq9cl0eg6NN6bYbPnR67ZLo7St5Q3UK0SnARw==",
"dev": true,
"requires": {
"undici-types": "~6.21.0"
}
},
"@ungap/structured-clone": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
@@ -8214,6 +8241,12 @@
"which-boxed-primitive": "^1.1.1"
}
},
"undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true
},
"update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",

View File

@@ -17,6 +17,7 @@
},
"devDependencies": {
"@preact/preset-vite": "^2.9.3",
"@types/node": "^22.15.23",
"eslint": "^8.57.1",
"eslint-config-preact": "^1.5.0",
"typescript": "^5.8.3",

92
package/composer.lock generated Normal file
View File

@@ -0,0 +1,92 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "ee7e3ad86855a67e00785a425ecb5246",
"packages": [
{
"name": "liquid/liquid",
"version": "1.4.32",
"source": {
"type": "git",
"url": "https://github.com/kalimatas/php-liquid.git",
"reference": "f0be8a3e0e0fcee99c0091748dcb21675b3caf46"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kalimatas/php-liquid/zipball/f0be8a3e0e0fcee99c0091748dcb21675b3caf46",
"reference": "f0be8a3e0e0fcee99c0091748dcb21675b3caf46",
"shasum": ""
},
"require": {
"php": "^7.3 || ^8.0"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.8",
"friendsofphp/php-cs-fixer": "^2.16.4",
"infection/infection": ">=0.17.6",
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^9.2.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Liquid\\": "src/Liquid"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guz Alexander",
"email": "kalimatas@gmail.com",
"homepage": "http://guzalexander.com"
},
{
"name": "Harald Hanek"
},
{
"name": "Mateo Murphy"
},
{
"name": "Alexey Kopytko",
"email": "alexey@kopytko.com",
"homepage": "https://www.alexeykopytko.com/"
}
],
"description": "Liquid template engine for PHP",
"homepage": "https://github.com/kalimatas/php-liquid",
"keywords": [
"liquid",
"template"
],
"support": {
"issues": "https://github.com/kalimatas/php-liquid/issues",
"source": "https://github.com/kalimatas/php-liquid/tree/1.4.32"
},
"time": "2022-08-08T01:55:20+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"ext-json": "*",
"ext-mysqli": "*",
"ext-zip": "*"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"
}

25
package/vendor/autoload.php vendored Normal file
View File

@@ -0,0 +1,25 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitee7e3ad86855a67e00785a425ecb5246::getLoader();

579
package/vendor/composer/ClassLoader.php vendored Normal file
View File

@@ -0,0 +1,579 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

View File

@@ -0,0 +1,359 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
return $installed;
}
}

21
package/vendor/composer/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,10 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
);

View File

@@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
);

View File

@@ -0,0 +1,10 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Liquid\\' => array($vendorDir . '/liquid/liquid/src/Liquid'),
);

View File

@@ -0,0 +1,38 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitee7e3ad86855a67e00785a425ecb5246
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInitee7e3ad86855a67e00785a425ecb5246', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitee7e3ad86855a67e00785a425ecb5246', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitee7e3ad86855a67e00785a425ecb5246::getInitializer($loader));
$loader->register(true);
return $loader;
}
}

View File

@@ -0,0 +1,36 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInitee7e3ad86855a67e00785a425ecb5246
{
public static $prefixLengthsPsr4 = array (
'L' =>
array (
'Liquid\\' => 7,
),
);
public static $prefixDirsPsr4 = array (
'Liquid\\' =>
array (
0 => __DIR__ . '/..' . '/liquid/liquid/src/Liquid',
),
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitee7e3ad86855a67e00785a425ecb5246::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitee7e3ad86855a67e00785a425ecb5246::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitee7e3ad86855a67e00785a425ecb5246::$classMap;
}, null, ClassLoader::class);
}
}

78
package/vendor/composer/installed.json vendored Normal file
View File

@@ -0,0 +1,78 @@
{
"packages": [
{
"name": "liquid/liquid",
"version": "1.4.32",
"version_normalized": "1.4.32.0",
"source": {
"type": "git",
"url": "https://github.com/kalimatas/php-liquid.git",
"reference": "f0be8a3e0e0fcee99c0091748dcb21675b3caf46"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kalimatas/php-liquid/zipball/f0be8a3e0e0fcee99c0091748dcb21675b3caf46",
"reference": "f0be8a3e0e0fcee99c0091748dcb21675b3caf46",
"shasum": ""
},
"require": {
"php": "^7.3 || ^8.0"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.8",
"friendsofphp/php-cs-fixer": "^2.16.4",
"infection/infection": ">=0.17.6",
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^9.2.6"
},
"time": "2022-08-08T01:55:20+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Liquid\\": "src/Liquid"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guz Alexander",
"email": "kalimatas@gmail.com",
"homepage": "http://guzalexander.com"
},
{
"name": "Harald Hanek"
},
{
"name": "Mateo Murphy"
},
{
"name": "Alexey Kopytko",
"email": "alexey@kopytko.com",
"homepage": "https://www.alexeykopytko.com/"
}
],
"description": "Liquid template engine for PHP",
"homepage": "https://github.com/kalimatas/php-liquid",
"keywords": [
"liquid",
"template"
],
"support": {
"issues": "https://github.com/kalimatas/php-liquid/issues",
"source": "https://github.com/kalimatas/php-liquid/tree/1.4.32"
},
"install-path": "../liquid/liquid"
}
],
"dev": true,
"dev-package-names": []
}

32
package/vendor/composer/installed.php vendored Normal file
View File

@@ -0,0 +1,32 @@
<?php return array(
'root' => array(
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '1c2e648b54daf6079ce591d9464594587ffb788d',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '1c2e648b54daf6079ce591d9464594587ffb788d',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'liquid/liquid' => array(
'pretty_version' => '1.4.32',
'version' => '1.4.32.0',
'reference' => 'f0be8a3e0e0fcee99c0091748dcb21675b3caf46',
'type' => 'library',
'install_path' => __DIR__ . '/../liquid/liquid',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

View File

@@ -0,0 +1,26 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 70300)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

View File

@@ -0,0 +1,5 @@
- [ ] I've run the tests with `vendor/bin/phpunit`
- [ ] None of the tests were found failing
- [ ] I've seen the coverage report at `build/coverage/index.html`
- [ ] Not a single line left uncovered by tests
- [ ] Any coding standards issues were fixed with `vendor/bin/php-cs-fixer fix`

View File

@@ -0,0 +1,46 @@
name: Code Style
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.3']
name: PHP ${{ matrix.php-version }}
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions:
coverage: pcov
tools: composer:v1
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ~/.cache/composer
key: composer-${{ matrix.php-version }}-${{ hashFiles('**/composer.*') }}
restore-keys: |
composer-${{ matrix.php-version }}-
composer-
- name: Install dependencies
run: |
composer update --prefer-dist --no-interaction --no-progress ${{ matrix.dependencies }}
- name: Check code style
run: |
php vendor/bin/php-cs-fixer --using-cache=no --diff --dry-run --stop-on-violation --verbose fix

View File

@@ -0,0 +1,48 @@
name: Mutation Testing
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.4']
dependencies: ['']
name: PHP ${{ matrix.php-version }} ${{ matrix.dependencies }}
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions:
coverage: pcov
tools: composer:v2
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ~/.cache/composer
key: composer-${{ matrix.php-version }}-${{ hashFiles('**/composer.*') }}
restore-keys: |
composer-${{ matrix.php-version }}-
composer-
- name: Install dependencies
run: |
composer update --prefer-dist --no-interaction --no-progress ${{ matrix.dependencies }}
- name: Run mutation testing
run: |
php vendor/bin/infection --min-msi=80 --min-covered-msi=80 --show-mutations --threads=$(nproc)

View File

@@ -0,0 +1,56 @@
# yamllint disable rule:line-length
# yamllint disable rule:braces
name: CI
on:
pull_request:
push:
branches:
- master
- main
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.3', '7.4', '8.0', '8.1']
include:
- { php-version: '7.3', dependencies: '--prefer-lowest', legend: 'with lowest dependencies' }
name: PHP ${{ matrix.php-version }} ${{ matrix.legend }}
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: pcov
tools: composer:v2
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.composer-flags }}
restore-keys: |
composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-
composer-${{ runner.os }}-${{ matrix.php-version }}-
composer-${{ runner.os }}-
composer-
- name: Install dependencies
run: |
composer update --prefer-dist --no-interaction --no-progress ${{ matrix.dependencies }}
- name: Run tests
run: |
php vendor/bin/phpunit

View File

@@ -0,0 +1,3 @@
.idea/
vendor/
composer.lock

View File

@@ -0,0 +1,42 @@
<?php
$header = <<<'EOF'
This file is part of the Liquid package.
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
@package Liquid
EOF;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'psr4' => true,
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'phpdoc_add_missing_param_annotation' => true,
'phpdoc_order' => true,
'semicolon_after_instruction' => true,
'whitespace_after_comma_in_array' => true,
'header_comment' => ['header' => $header],
'php_unit_construct' => true,
'php_unit_dedicate_assert' => true,
'php_unit_dedicate_assert_internal_type' => true,
'php_unit_expectation' => true,
'php_unit_mock_short_will_return' => true,
'php_unit_mock' => true,
'php_unit_namespaced' => true,
'php_unit_no_expectation_annotation' => true,
'php_unit_ordered_covers' => true,
'php_unit_set_up_tear_down_visibility' => true,
'php_unit_test_case_static_method_calls' => ['call_type' => 'this'],
])
->setIndent("\t")
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__)
)
;

View File

@@ -0,0 +1,107 @@
## master
## 1.4.8 (2018-03-22)
* Now we return null for missing properties, like we do for missing keys for arrays.
## 1.4.7 (2018-02-09)
* Paginate tag shall now respect request parameters.
* It is now possible to set a custom query param for the paginate tag.
* Page number will now never go overboard.
## 1.4.6 (2018-02-07)
* TagPaginate shall not pollute the global scope, but work in own scope.
* TagPaginate errors if no collection present instead of vague warning.
## 1.4.5 (2017-12-12)
* Capture tag shall save a variable in the global context.
## 1.4.4 (2017-11-03)
* TagUnless is an inverted TagIf: simplified implementation
* Allow dashes in filenames
## 1.4.3 (2017-10-10)
* `escape` and `escape_once` filters now escape everything, but arrays
* New standard filter for explicit string conversion
## 1.4.2 (2017-10-09)
* Better caching for non-extending templates
* Simplified 'assign' tag to use rules for variables
* Now supporting PHP 7.2
* Different types of exception depending on the case
* Filterbank will not call instance methods statically
* Callback-type filters
## 1.4.1 (2017-09-28)
* Unquoted template names in 'include' tag, as in Jekyll
* Caching now works correctly with 'extends' tag
## 1.4.0 (2017-09-25)
* Dropped support for EOL'ed versions of PHP (< 5.6)
* Arrays won't be silently cast to string as 'Array' anymore
* Complex objects could now be passed between templates and to filters
* Additional test coverage
## 1.3.1 (2017-09-23)
* Support for numeric and variable array indicies
* Support loop break and continue
* Allow looping over extended ranges
* Math filters now work with floats
* Fixed 'default' filter
* Local cache with data stored in a private variable
* Virtual file system to get inversion of control and DI
* Lots of tests with the coverage upped to 97%
* Small bug fixes and various enhancements
## 1.3.0 (2017-07-17)
* Support Traversable loops and filters
* Fix date filter for format with colon
* Various minor improvements and bugs fixes
## 1.2.1 (2016-12-12)
* Remove content injection from $_GET.
* Add PHP 5.6, 7.0, 7.1 to Travis file.
## 1.2 (2016-06-11)
* Added "ESCAPE_BY_DEFAULT" setting for context-aware auto-escaping.
* Made "Context" work with plain objects.
* "escape" now uses "htmlentities".
* Fixed "escape_now".
## 1.1 (2015-06-01)
* New tags: "paginate", "unless", "ifchanged" were added
* Added support for "for in (range)" syntax
* Added support for multiple conditions in if statements
* Added support for hashes/objects in for loops
## 1.0 (2014-09-07)
* Add namespaces
* Add composer support
* Implement new standard filters
* Add 'raw' tag
## 0.9.2 (2012-08-15)
* context->set allows now global vars
* Allow Templatenames with Fileextension
* Tag 'extends' supports now multiple inheritance
* Clean up code, change all variables and methods to camelCase
## 0.9.1 (2012-05-12)
* added the extends and block filter
* Initial release

22
package/vendor/liquid/liquid/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2014 Guz Alexander, http://guzalexander.com
Copyright (c) 2011, 2012 Harald Hanek, http://www.delacap.com
Copyright (c) 2006 Mateo Murphy
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

139
package/vendor/liquid/liquid/README.md vendored Normal file
View File

@@ -0,0 +1,139 @@
# Liquid template engine for PHP [![CI](https://github.com/kalimatas/php-liquid/actions/workflows/tests.yaml/badge.svg)](https://github.com/kalimatas/php-liquid/actions/workflows/tests.yaml) [![Coverage Status](https://coveralls.io/repos/github/kalimatas/php-liquid/badge.svg?branch=master)](https://coveralls.io/github/kalimatas/php-liquid?branch=master) [![Total Downloads](https://poser.pugx.org/liquid/liquid/downloads.svg)](https://packagist.org/packages/liquid/liquid)
Liquid is a PHP port of the [Liquid template engine for Ruby](https://github.com/Shopify/liquid), which was written by Tobias Lutke. Although there are many other templating engines for PHP, including Smarty (from which Liquid was partially inspired), Liquid had some advantages that made porting worthwhile:
* Readable and human friendly syntax, that is usable in any type of document, not just html, without need for escaping.
* Quick and easy to use and maintain.
* 100% secure, no possibility of embedding PHP code.
* Clean OO design, rather than the mix of OO and procedural found in other templating engines.
* Seperate compiling and rendering stages for improved performance.
* Easy to extend with your own "tags and filters":https://github.com/harrydeluxe/php-liquid/wiki/Liquid-for-programmers.
* 100% Markup compatibility with a Ruby templating engine, making templates usable for either.
* Unit tested: Liquid is fully unit-tested. The library is stable and ready to be used in large projects.
## Why Liquid?
Why another templating library?
Liquid was written to meet three templating library requirements: good performance, easy to extend, and simply to use.
## Installing
You can install this lib via [composer](https://getcomposer.org/):
composer require liquid/liquid
## Example template
{% if products %}
<ul id="products">
{% for product in products %}
<li>
<h2>{{ product.name }}</h2>
Only {{ product.price | price }}
{{ product.description | prettyprint | paragraph }}
{{ 'it rocks!' | paragraph }}
</li>
{% endfor %}
</ul>
{% endif %}
## How to use Liquid
The main class is `Liquid::Template` class. There are two separate stages of working with Liquid templates: parsing and rendering. Here is a simple example:
use Liquid\Template;
$template = new Template();
$template->parse("Hello, {{ name }}!");
echo $template->render(array('name' => 'Alex'));
// Will echo
// Hello, Alex!
To find more examples have a look at the `examples` directory or at the original Ruby implementation repository's [wiki page](https://github.com/Shopify/liquid/wiki).
## Advanced usage
You would probably want to add a caching layer (at very least a request-wide one), enable context-aware automatic escaping, and do load includes from disk with full file names.
use Liquid\Liquid;
use Liquid\Template;
use Liquid\Cache\Local;
Liquid::set('INCLUDE_SUFFIX', '');
Liquid::set('INCLUDE_PREFIX', '');
Liquid::set('INCLUDE_ALLOW_EXT', true);
Liquid::set('ESCAPE_BY_DEFAULT', true);
$template = new Template(__DIR__.'/protected/templates/');
$template->parse("Hello, {% include 'honorific.html' %}{{ plain-html | raw }} {{ comment-with-xss }}");
$template->setCache(new Local());
echo $template->render([
'name' => 'Alex',
'plain-html' => '<b>Your comment was:</b>',
'comment-with-xss' => '<script>alert();</script>',
]);
Will output:
Hello, Mx. Alex
<b>Your comment was:</b> &lt;script&gt;alert();&lt;/script&gt;
Note that automatic escaping is not a standard Liquid feature: use with care.
Similarly, the following snippet will parse and render `templates/home.liquid` while storing parsing results in a class-local cache:
\Liquid\Liquid::set('INCLUDE_PREFIX', '');
$template = new \Liquid\Template(__DIR__ . '/protected/templates');
$template->setCache(new \Liquid\Cache\Local());
echo $template->parseFile('home')->render();
If you render the same template over and over for at least a dozen of times, the class-local cache will give you a slight speed up in range of some milliseconds per render depending on a complexity of your template.
You should probably extend `Liquid\Template` to initialize everything you do with `Liquid::set` in one place.
### Custom filters
Adding filters has never been easier.
$template = new Template();
$template->registerFilter('absolute_url', function ($arg) {
return "https://www.example.com$arg";
});
$template->parse("{{ my_url | absolute_url }}");
echo $template->render(array(
'my_url' => '/test'
));
// expect: https://www.example.com/test
## Requirements
* PHP 7.0+
Some earlier versions could be used with PHP 5.3/5.4/5.5/5.6, though they're not supported anymore.
## Issues
Have a bug? Please create an issue here on GitHub!
[https://github.com/kalimatas/php-liquid/issues](https://github.com/kalimatas/php-liquid/issues)
## Fork notes
This fork is based on [php-liquid](https://github.com/harrydeluxe/php-liquid) by Harald Hanek.
It contains several improvements:
* namespaces
* installing via composer
* new standard filters
* `raw` tag added
Any help is appreciated!

View File

@@ -0,0 +1,58 @@
{
"name": "liquid/liquid",
"type": "library",
"description": "Liquid template engine for PHP",
"keywords": [
"liquid",
"template"
],
"homepage": "https://github.com/kalimatas/php-liquid",
"license": "MIT",
"authors": [
{
"name": "Guz Alexander",
"email": "kalimatas@gmail.com",
"homepage": "http://guzalexander.com"
},
{
"name": "Harald Hanek"
},
{
"name": "Mateo Murphy"
},
{
"name": "Alexey Kopytko",
"email": "alexey@kopytko.com",
"homepage": "https://www.alexeykopytko.com/"
}
],
"require": {
"php": "^7.3 || ^8.0"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.8",
"friendsofphp/php-cs-fixer": "^2.16.4",
"infection/infection": ">=0.17.6",
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^9.2.6"
},
"config": {
"sort-packages": true,
"allow-plugins": true
},
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Liquid\\": "src/Liquid"
}
},
"autoload-dev": {
"psr-4": {
"Liquid\\": "tests/Liquid"
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
require __DIR__ . '/../vendor/autoload.php';
use Liquid\Liquid;
use Liquid\Template;
use Liquid\Cache\Local;
Liquid::set('INCLUDE_SUFFIX', '');
Liquid::set('INCLUDE_PREFIX', '');
Liquid::set('INCLUDE_ALLOW_EXT', true);
Liquid::set('ESCAPE_BY_DEFAULT', true);
$template = new Template(__DIR__.'/protected/templates/');
$template->parse("Hello, {% include 'honorific.html' %}{{ plain-html | raw }} {{ comment-with-xss }}\n");
$template->setCache(new Local());
echo $template->render([
'name' => 'Alex',
'plain-html' => '<b>Your comment was:</b>',
'comment-with-xss' => '<script>alert();</script>',
]);

View File

@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
require __DIR__ . '/../vendor/autoload.php';
use Liquid\Liquid;
use Liquid\Template;
Liquid::set('INCLUDE_ALLOW_EXT', true);
$protectedPath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'protected' . DIRECTORY_SEPARATOR;
$liquid = new Template($protectedPath . 'templates' . DIRECTORY_SEPARATOR);
// Uncomment the following lines to enable cache
//$cache = array('cache' => 'file', 'cache_dir' => $protectedPath . 'cache' . DIRECTORY_SEPARATOR);
// or if you have APC installed
//$cache = array('cache' => 'apc');
//$liquid->setCache($cache);
$liquid->parse(file_get_contents($protectedPath . 'templates' . DIRECTORY_SEPARATOR . 'child.tpl'));
$assigns = array(
'document' => array(
'title' => 'This is php-liquid',
'content' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.',
'copyright' => '&copy; Copyright 2014 Guz Alexander - All rights reserved.',
),
);
echo $liquid->render($assigns);

View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
require __DIR__ . '/../vendor/autoload.php';
use Liquid\Liquid;
use Liquid\Template;
$template = new Template();
$template->registerFilter('absolute_url', function ($arg) {
return "https://www.example.com$arg";
});
$template->parse("{{ my_url | absolute_url }}");
echo $template->render(array(
'my_url' => '/test'
));
// expect: https://www.example.com/test

View File

@@ -0,0 +1,70 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
require __DIR__ . '/../vendor/autoload.php';
use Liquid\Liquid;
use Liquid\Template;
Liquid::set('INCLUDE_SUFFIX', 'tpl');
Liquid::set('INCLUDE_PREFIX', '');
$protectedPath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'protected' . DIRECTORY_SEPARATOR;
$liquid = new Template($protectedPath . 'templates' . DIRECTORY_SEPARATOR);
// Uncomment the following lines to enable cache
//$cache = array('cache' => 'file', 'cache_dir' => $protectedPath . 'cache' . DIRECTORY_SEPARATOR);
// or if you have APC installed
//$cache = array('cache' => 'apc');
//$liquid->setCache($cache);
$liquid->parse(file_get_contents($protectedPath . 'templates' . DIRECTORY_SEPARATOR . 'index.tpl'));
$assigns = array(
'document' => array(
'title' => 'This is php-liquid',
'content' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.',
'copyright' => 'Guz Alexander - All rights reserved.',
),
'blog' => array(
array(
'title' => 'Blog Title 1',
'content' => 'Nunc putamus parum claram',
'tags' => array('claram', 'parum'),
'comments' => array(
array(
'title' => 'First Comment',
'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr',
),
),
),
array(
'title' => 'Blog Title 2',
'content' => 'Nunc putamus parum claram',
'tags' => array('claram', 'parum', 'freestyle'),
'comments' => array(
array(
'title' => 'First Comment',
'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr',
),
array(
'title' => 'Second Comment',
'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr',
),
),
),
),
'array' => array('one', 'two', 'three', 'four'),
);
echo $liquid->render($assigns);

View File

@@ -0,0 +1,2 @@
!.gitignore
liquid_*

View File

@@ -0,0 +1,15 @@
{% comment %} This is the base template. {% endcomment %}
<!DOCTYPE HTML>
<html>
<head>
{% include 'header.tpl' %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
&copy; Copyright 2014 by <a href="http://guzalexander.com/">Guz Alexander</a>.
{% endblock %}
</div>
</body>
</html>

View File

@@ -0,0 +1,6 @@
{% comment %} This is the child template. {% endcomment %}
{% extends "base.tpl" %}
{% block footer %}
{{ document.copyright }}
{% endblock %}

View File

@@ -0,0 +1,7 @@
{% comment %} This is the child template. {% endcomment %}
{% extends "blocks/child.tpl" %}
{% block content %}
<h2>Entry one</h2>
<p>This is my first entry.</p>
{% endblock %}

View File

@@ -0,0 +1,3 @@
<div id="footer">
&copy; {{ 'now' | date: "%Y" }} {% include 'subfooter' %}
</div>

View File

@@ -0,0 +1,2 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>{{ document.title }}</title>

View File

@@ -0,0 +1 @@
Mx. {{ name }}

View File

@@ -0,0 +1,44 @@
{% comment %}
This is a comment block
(c) 2014 Guz Alexander
{% endcomment %}
<!DOCTYPE HTML>
<html>
<head>
{% include 'header' %}
</head>
<body>
<h1>{{ document.title }}</h1>
<p>{{ document.content }}</p>
<p><a href="simple.php">Link to simple.php</a></p>
{% if blog %}
Total Blogentrys: {{ blog | size }}
<ul id="products">
{% for entry in blog %}
<li>
<h3>{{ entry.title | upcase }}</h3>
<p>{{ entry.content }}</p>
Comments: {{ entry.comments | size }}
{% assign uzu = 'dudu2' %}
{% assign freestyle = false %}
{% for t in entry.tags %}
{% if t == 'freestyle' %}
{% assign freestyle = true %}
{% endif %}
{% endfor %}
{% if freestyle %}
<p>Blogentry has tag: freestyle</p>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% include 'footer' %}
</body>
</html>

View File

@@ -0,0 +1 @@
{{ document.copyright }}

View File

@@ -0,0 +1,23 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
require __DIR__ . '/../vendor/autoload.php';
use Liquid\Liquid;
use Liquid\Template;
Liquid::set('INCLUDE_SUFFIX', 'tpl');
Liquid::set('INCLUDE_PREFIX', '');
$liquid = new Template();
$liquid->parse('{{ hello }} {{ goback }}');
echo $liquid->render(array('hello' => 'hello world', 'goback' => '<a href=".">index</a>'));

View File

@@ -0,0 +1,8 @@
{
"timeout": 2,
"source": {
"directories": [
"src"
]
}
}

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
executionOrder="random"
resolveDependencies="true"
failOnRisky="true"
failOnWarning="true"
backupStaticAttributes="true"
>
<testsuites>
<testsuite name="Main">
<directory>tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -0,0 +1,264 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
use Liquid\Exception\ParseException;
use Liquid\Exception\RenderException;
/**
* Base class for blocks.
*/
class AbstractBlock extends AbstractTag
{
const TAG_PREFIX = '\Liquid\Tag\Tag';
/**
* @var AbstractTag[]|Variable[]|string[]
*/
protected $nodelist = array();
/**
* Whenever next token should be ltrim'med.
*
* @var bool
*/
protected static $trimWhitespace = false;
/**
* @return array
*/
public function getNodelist()
{
return $this->nodelist;
}
/**
* Parses the given tokens
*
* @param array $tokens
*
* @throws \Liquid\LiquidException
* @return void
*/
public function parse(array &$tokens)
{
$startRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '/');
$tagRegexp = new Regexp('/^' . Liquid::get('TAG_START') . Liquid::get('WHITESPACE_CONTROL') . '?\s*(\w+)\s*(.*?)' . Liquid::get('WHITESPACE_CONTROL') . '?' . Liquid::get('TAG_END') . '$/s');
$variableStartRegexp = new Regexp('/^' . Liquid::get('VARIABLE_START') . '/');
$this->nodelist = array();
$tags = Template::getTags();
while (count($tokens)) {
$token = array_shift($tokens);
if ($startRegexp->match($token)) {
$this->whitespaceHandler($token);
if ($tagRegexp->match($token)) {
// If we found the proper block delimitor just end parsing here and let the outer block proceed
if ($tagRegexp->matches[1] == $this->blockDelimiter()) {
$this->endTag();
return;
}
$tagName = null;
if (array_key_exists($tagRegexp->matches[1], $tags)) {
$tagName = $tags[$tagRegexp->matches[1]];
} else {
$tagName = self::TAG_PREFIX . ucwords($tagRegexp->matches[1]);
$tagName = (class_exists($tagName) === true) ? $tagName : null;
}
if ($tagName !== null) {
$this->nodelist[] = new $tagName($tagRegexp->matches[2], $tokens, $this->fileSystem);
if ($tagRegexp->matches[1] == 'extends') {
return;
}
} else {
$this->unknownTag($tagRegexp->matches[1], $tagRegexp->matches[2], $tokens);
}
} else {
throw new ParseException("Tag $token was not properly terminated (won't match $tagRegexp)");
}
} elseif ($variableStartRegexp->match($token)) {
$this->whitespaceHandler($token);
$this->nodelist[] = $this->createVariable($token);
} else {
// This is neither a tag or a variable, proceed with an ltrim
if (self::$trimWhitespace) {
$token = ltrim($token);
}
self::$trimWhitespace = false;
$this->nodelist[] = $token;
}
}
$this->assertMissingDelimitation();
}
/**
* Handle the whitespace.
*
* @param string $token
*/
protected function whitespaceHandler($token)
{
/*
* This assumes that TAG_START is always '{%', and a whitespace control indicator
* is exactly one character long, on a third position.
*/
if (mb_substr($token, 2, 1) === Liquid::get('WHITESPACE_CONTROL')) {
$previousToken = end($this->nodelist);
if (is_string($previousToken)) { // this can also be a tag or a variable
$this->nodelist[key($this->nodelist)] = rtrim($previousToken);
}
}
/*
* This assumes that TAG_END is always '%}', and a whitespace control indicator
* is exactly one character long, on a third position from the end.
*/
self::$trimWhitespace = mb_substr($token, -3, 1) === Liquid::get('WHITESPACE_CONTROL');
}
/**
* Render the block.
*
* @param Context $context
*
* @return string
*/
public function render(Context $context)
{
return $this->renderAll($this->nodelist, $context);
}
/**
* Renders all the given nodelist's nodes
*
* @param array $list
* @param Context $context
*
* @return string
*/
protected function renderAll(array $list, Context $context)
{
$result = '';
foreach ($list as $token) {
if (is_object($token) && method_exists($token, 'render')) {
$value = $token->render($context);
} else {
$value = $token;
}
if (is_array($value)) {
$value = htmlspecialchars(print_r($value, true));
}
$result .= $value;
if (isset($context->registers['break'])) {
break;
}
if (isset($context->registers['continue'])) {
break;
}
$context->tick();
}
return $result;
}
/**
* An action to execute when the end tag is reached
*/
protected function endTag()
{
// Do nothing by default
}
/**
* Handler for unknown tags
*
* @param string $tag
* @param string $params
* @param array $tokens
*
* @throws \Liquid\Exception\ParseException
*/
protected function unknownTag($tag, $params, array $tokens)
{
switch ($tag) {
case 'else':
throw new ParseException($this->blockName() . " does not expect else tag");
case 'end':
throw new ParseException("'end' is not a valid delimiter for " . $this->blockName() . " tags. Use " . $this->blockDelimiter());
default:
throw new ParseException("Unknown tag $tag");
}
}
/**
* This method is called at the end of parsing, and will throw an error unless
* this method is subclassed, like it is for Document
*
* @throws \Liquid\Exception\ParseException
* @return bool
*/
protected function assertMissingDelimitation()
{
throw new ParseException($this->blockName() . " tag was never closed");
}
/**
* Returns the string that delimits the end of the block
*
* @return string
*/
protected function blockDelimiter()
{
return "end" . $this->blockName();
}
/**
* Returns the name of the block
*
* @return string
*/
private function blockName()
{
$reflection = new \ReflectionClass($this);
return str_replace('tag', '', strtolower($reflection->getShortName()));
}
/**
* Create a variable for the given token
*
* @param string $token
*
* @throws \Liquid\Exception\ParseException
* @return Variable
*/
private function createVariable($token)
{
$variableRegexp = new Regexp('/^' . Liquid::get('VARIABLE_START') . Liquid::get('WHITESPACE_CONTROL') . '?(.*?)' . Liquid::get('WHITESPACE_CONTROL') . '?' . Liquid::get('VARIABLE_END') . '$/s');
if ($variableRegexp->match($token)) {
return new Variable($variableRegexp->matches[1]);
}
throw new ParseException("Variable $token was not properly terminated");
}
}

View File

@@ -0,0 +1,100 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* Base class for tags.
*/
abstract class AbstractTag
{
/**
* The markup for the tag
*
* @var string
*/
protected $markup;
/**
* Filesystem object is used to load included template files
*
* @var FileSystem
*/
protected $fileSystem;
/**
* Additional attributes
*
* @var array
*/
protected $attributes = array();
/**
* Constructor.
*
* @param string $markup
* @param array $tokens
* @param FileSystem $fileSystem
*/
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
{
$this->markup = $markup;
$this->fileSystem = $fileSystem;
$this->parse($tokens);
}
/**
* Parse the given tokens.
*
* @param array $tokens
*/
public function parse(array &$tokens)
{
// Do nothing by default
}
/**
* Render the tag with the given context.
*
* @param Context $context
*
* @return string
*/
abstract public function render(Context $context);
/**
* Extracts tag attributes from a markup string.
*
* @param string $markup
*/
protected function extractAttributes($markup)
{
$this->attributes = array();
$attributeRegexp = new Regexp(Liquid::get('TAG_ATTRIBUTES'));
$matches = $attributeRegexp->scan($markup);
foreach ($matches as $match) {
$this->attributes[$match[0]] = $match[1];
}
}
/**
* Returns the name of the tag.
*
* @return string
*/
protected function name()
{
return strtolower(get_class($this));
}
}

View File

@@ -0,0 +1,78 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* Base class for Cache.
*/
abstract class Cache
{
/** @var int */
protected $expire = 3600;
/** @var string */
protected $prefix = 'liquid_';
/** @var string */
protected $path;
/**
* @param array $options
*/
public function __construct(array $options = array())
{
if (isset($options['cache_expire'])) {
$this->expire = $options['cache_expire'];
}
if (isset($options['cache_prefix'])) {
$this->prefix = $options['cache_prefix'];
}
}
/**
* Retrieves a value from cache with a specified key.
*
* @param string $key a unique key identifying the cached value
* @param bool $unserialize
*
* @return mixed|boolean the value stored in cache, false if the value is not in the cache or expired.
*/
abstract public function read($key, $unserialize = true);
/**
* Check if specified key exists in cache.
*
* @param string $key a unique key identifying the cached value
*
* @return boolean true if the key is in cache, false otherwise
*/
abstract public function exists($key);
/**
* Stores a value identified by a key in cache.
*
* @param string $key the key identifying the value to be cached
* @param mixed $value the value to be cached
* @param bool $serialize
*
* @return boolean true if the value is successfully stored into cache, false otherwise
*/
abstract public function write($key, $value, $serialize = true);
/**
* Deletes all values from cache.
*
* @param bool $expiredOnly
*
* @return boolean whether the flush operation was successful.
*/
abstract public function flush($expiredOnly = false);
}

View File

@@ -0,0 +1,74 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Cache;
use Liquid\Cache;
use Liquid\LiquidException;
/**
* Implements cache stored in Apc.
*
* @codeCoverageIgnore
*/
class Apc extends Cache
{
/**
* Constructor.
*
* It checks the availability of apccache.
*
* @param array $options
*
* @throws LiquidException if APC cache extension is not loaded or is disabled.
*/
public function __construct(array $options = array())
{
parent::__construct($options);
if (!function_exists('apc_fetch')) {
throw new LiquidException(get_class($this).' requires PHP apc extension or similar to be loaded.');
}
}
/**
* {@inheritdoc}
*/
public function read($key, $unserialize = true)
{
return apc_fetch($this->prefix . $key);
}
/**
* {@inheritdoc}
*/
public function exists($key)
{
apc_fetch($this->prefix . $key, $success);
return (bool) $success;
}
/**
* {@inheritdoc}
*/
public function write($key, $value, $serialize = true)
{
return apc_store($this->prefix . $key, $value, $this->expire);
}
/**
* {@inheritdoc}
*/
public function flush($expiredOnly = false)
{
return apc_clear_cache('user');
}
}

View File

@@ -0,0 +1,106 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Cache;
use Liquid\Cache;
use Liquid\Exception\NotFoundException;
/**
* Implements cache stored in files.
*/
class File extends Cache
{
/**
* Constructor.
*
* It checks the availability of cache directory.
*
* @param array $options
*
* @throws NotFoundException if Cachedir not exists.
*/
public function __construct(array $options = array())
{
parent::__construct($options);
if (isset($options['cache_dir']) && is_writable($options['cache_dir'])) {
$this->path = realpath($options['cache_dir']) . DIRECTORY_SEPARATOR;
} else {
throw new NotFoundException('Cachedir not exists or not writable');
}
}
/**
* {@inheritdoc}
*/
public function read($key, $unserialize = true)
{
if (!$this->exists($key)) {
return false;
}
if ($unserialize) {
return unserialize(file_get_contents($this->path . $this->prefix . $key));
}
return file_get_contents($this->path . $this->prefix . $key);
}
/**
* {@inheritdoc}
*/
public function exists($key)
{
$cacheFile = $this->path . $this->prefix . $key;
if (!file_exists($cacheFile) || filemtime($cacheFile) + $this->expire < time()) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
public function write($key, $value, $serialize = true)
{
$bytes = file_put_contents($this->path . $this->prefix . $key, $serialize ? serialize($value) : $value);
$this->gc();
return $bytes !== false;
}
/**
* {@inheritdoc}
*/
public function flush($expiredOnly = false)
{
foreach (glob($this->path . $this->prefix . '*') as $file) {
if ($expiredOnly) {
if (filemtime($file) + $this->expire < time()) {
unlink($file);
}
} else {
unlink($file);
}
}
}
/**
* {@inheritdoc}
*/
protected function gc()
{
$this->flush(true);
}
}

View File

@@ -0,0 +1,60 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Cache;
use Liquid\Cache;
/**
* Implements cache with data stored in an embedded variable with no handling of expiration dates for simplicity
*/
class Local extends Cache
{
private $cache = array();
/**
* {@inheritdoc}
*/
public function read($key, $unserialize = true)
{
if (isset($this->cache[$key])) {
return $this->cache[$key];
}
return false;
}
/**
* {@inheritdoc}
*/
public function exists($key)
{
return isset($this->cache[$key]);
}
/**
* {@inheritdoc}
*/
public function write($key, $value, $serialize = true)
{
$this->cache[$key] = $value;
return true;
}
/**
* {@inheritdoc}
*/
public function flush($expiredOnly = false)
{
$this->cache = array();
return true;
}
}

View File

@@ -0,0 +1,458 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* Context keeps the variable stack and resolves variables, as well as keywords.
*/
class Context
{
/**
* Local scopes
*
* @var array
*/
protected $assigns;
/**
* Registers for non-variable state data
*
* @var array
*/
public $registers;
/**
* The filterbank holds all the filters
*
* @var Filterbank
*/
protected $filterbank;
/**
* Global scopes
*
* @var array
*/
public $environments = array();
/**
* Called "sometimes" while rendering. For example to abort the execution of a rendering.
*
* @var null|callable
*/
private $tickFunction = null;
/**
* Constructor
*
* @param array $assigns
* @param array $registers
*/
public function __construct(array $assigns = array(), array $registers = array())
{
$this->assigns = array($assigns);
$this->registers = $registers;
$this->filterbank = new Filterbank($this);
// first empty array serves as source for overrides, e.g. as in TagDecrement
$this->environments = array(array(), array());
if (Liquid::get('EXPOSE_SERVER')) {
$this->environments[1] = $_SERVER;
} else {
$this->environments[1] = array_filter(
$_SERVER,
function ($key) {
return in_array(
$key,
(array)Liquid::get('SERVER_SUPERGLOBAL_WHITELIST')
);
},
ARRAY_FILTER_USE_KEY
);
}
}
/**
* Sets a tick function, this function is called sometimes while liquid is rendering a template.
*
* @param callable $tickFunction
*/
public function setTickFunction(callable $tickFunction)
{
$this->tickFunction = $tickFunction;
}
/**
* Add a filter to the context
*
* @param mixed $filter
*/
public function addFilters($filter, callable $callback = null)
{
$this->filterbank->addFilter($filter, $callback);
}
/**
* Invoke the filter that matches given name
*
* @param string $name The name of the filter
* @param mixed $value The value to filter
* @param array $args Additional arguments for the filter
*
* @return string
*/
public function invoke($name, $value, array $args = array())
{
try {
return $this->filterbank->invoke($name, $value, $args);
} catch (\TypeError $typeError) {
throw new LiquidException($typeError->getMessage(), 0, $typeError);
}
}
/**
* Merges the given assigns into the current assigns
*
* @param array $newAssigns
*/
public function merge($newAssigns)
{
$this->assigns[0] = array_merge($this->assigns[0], $newAssigns);
}
/**
* Push new local scope on the stack.
*
* @return bool
*/
public function push()
{
array_unshift($this->assigns, array());
return true;
}
/**
* Pops the current scope from the stack.
*
* @throws LiquidException
* @return bool
*/
public function pop()
{
if (count($this->assigns) == 1) {
throw new LiquidException('No elements to pop');
}
array_shift($this->assigns);
}
/**
* Replaces []
*
* @param string
* @param mixed $key
*
* @return mixed
*/
public function get($key)
{
return $this->resolve($key);
}
/**
* Replaces []=
*
* @param string $key
* @param mixed $value
* @param bool $global
*/
public function set($key, $value, $global = false)
{
if ($global) {
for ($i = 0; $i < count($this->assigns); $i++) {
$this->assigns[$i][$key] = $value;
}
} else {
$this->assigns[0][$key] = $value;
}
}
/**
* Returns true if the given key will properly resolve
*
* @param string $key
*
* @return bool
*/
public function hasKey($key)
{
return (!is_null($this->resolve($key)));
}
/**
* Resolve a key by either returning the appropriate literal or by looking up the appropriate variable
*
* Test for empty has been moved to interpret condition, in Decision
*
* @param string $key
*
* @throws LiquidException
* @return mixed
*/
private function resolve($key)
{
// This shouldn't happen
if (is_array($key)) {
throw new LiquidException("Cannot resolve arrays as key");
}
if (is_null($key) || $key == 'null') {
return null;
}
if ($key == 'true') {
return true;
}
if ($key == 'false') {
return false;
}
if (preg_match('/^\'(.*)\'$/', $key, $matches)) {
return $matches[1];
}
if (preg_match('/^"(.*)"$/', $key, $matches)) {
return $matches[1];
}
if (preg_match('/^(-?\d+)$/', $key, $matches)) {
return $matches[1];
}
if (preg_match('/^(-?\d[\d\.]+)$/', $key, $matches)) {
return $matches[1];
}
return $this->variable($key);
}
/**
* Fetches the current key in all the scopes
*
* @param string $key
*
* @return mixed
*/
private function fetch($key)
{
// TagDecrement depends on environments being checked before assigns
foreach ($this->environments as $environment) {
if (array_key_exists($key, $environment)) {
return $environment[$key];
}
}
foreach ($this->assigns as $scope) {
if (array_key_exists($key, $scope)) {
$obj = $scope[$key];
if ($obj instanceof Drop) {
$obj->setContext($this);
}
return $obj;
}
}
return null;
}
/**
* Resolved the namespaced queries gracefully.
*
* @param string $key
*
* @see Decision::stringValue
* @see AbstractBlock::renderAll
*
* @throws LiquidException
* @return mixed
*/
private function variable($key)
{
// Support numeric and variable array indicies
if (preg_match("|\[[0-9]+\]|", $key)) {
$key = preg_replace("|\[([0-9]+)\]|", ".$1", $key);
} elseif (preg_match("|\[[0-9a-z._]+\]|", $key, $matches)) {
$index = $this->get(str_replace(array("[", "]"), "", $matches[0]));
if (strlen($index)) {
$key = preg_replace("|\[([0-9a-z._]+)\]|", ".$index", $key);
}
}
$parts = explode(Liquid::get('VARIABLE_ATTRIBUTE_SEPARATOR'), $key);
$object = $this->fetch(array_shift($parts));
while (count($parts) > 0) {
// since we still have a part to consider
// and since we can't dig deeper into plain values
// it can be thought as if it has a property with a null value
if (!is_object($object) && !is_array($object) && !is_string($object)) {
return null;
}
// first try to cast an object to an array or value
if (is_object($object)) {
if (method_exists($object, 'toLiquid')) {
$object = $object->toLiquid();
} elseif (method_exists($object, 'toArray')) {
$object = $object->toArray();
}
}
if (is_null($object)) {
return null;
}
if ($object instanceof Drop) {
$object->setContext($this);
}
$nextPartName = array_shift($parts);
if (is_string($object)) {
if ($nextPartName == 'size') {
// if the last part of the context variable is .size we return the string length
return mb_strlen($object);
}
// no other special properties for strings, yet
return null;
}
if (is_array($object)) {
// if the last part of the context variable is .first we return the first array element
if ($nextPartName == 'first' && count($parts) == 0 && !array_key_exists('first', $object)) {
return StandardFilters::first($object);
}
// if the last part of the context variable is .last we return the last array element
if ($nextPartName == 'last' && count($parts) == 0 && !array_key_exists('last', $object)) {
return StandardFilters::last($object);
}
// if the last part of the context variable is .size we just return the count
if ($nextPartName == 'size' && count($parts) == 0 && !array_key_exists('size', $object)) {
return count($object);
}
// no key - no value
if (!array_key_exists($nextPartName, $object)) {
return null;
}
$object = $object[$nextPartName];
continue;
}
if (!is_object($object)) {
// we got plain value, yet asked to resolve a part
// think plain values have a null part with any name
return null;
}
if ($object instanceof \Countable) {
// if the last part of the context variable is .size we just return the count
if ($nextPartName == 'size' && count($parts) == 0) {
return count($object);
}
}
if ($object instanceof Drop) {
// if the object is a drop, make sure it supports the given method
if (!$object->hasKey($nextPartName)) {
return null;
}
$object = $object->invokeDrop($nextPartName);
continue;
}
// if it has `get` or `field_exists` methods
if (method_exists($object, Liquid::get('HAS_PROPERTY_METHOD'))) {
if (!call_user_func(array($object, Liquid::get('HAS_PROPERTY_METHOD')), $nextPartName)) {
return null;
}
$object = call_user_func(array($object, Liquid::get('GET_PROPERTY_METHOD')), $nextPartName);
continue;
}
// if it's just a regular object, attempt to access a public method
if (is_callable(array($object, $nextPartName))) {
$object = call_user_func(array($object, $nextPartName));
continue;
}
// if a magic accessor method present...
if (is_object($object) && method_exists($object, '__get')) {
$object = $object->$nextPartName;
continue;
}
// Inexistent property is a null, PHP-speak
if (!property_exists($object, $nextPartName)) {
return null;
}
// then try a property (independent of accessibility)
if (property_exists($object, $nextPartName)) {
$object = $object->$nextPartName;
continue;
}
// we'll try casting this object in the next iteration
}
// lastly, try to get an embedded value of an object
// value could be of any type, not just string, so we have to do this
// conversion here, not later in AbstractBlock::renderAll
if (is_object($object) && method_exists($object, 'toLiquid')) {
$object = $object->toLiquid();
}
/*
* Before here were checks for object types and object to string conversion.
*
* Now we just return what we have:
* - Traversable objects are taken care of inside filters
* - Object-to-string conversion is handled at the last moment in Decision::stringValue, and in AbstractBlock::renderAll
*
* This way complex objects could be passed between templates and to filters
*/
return $object;
}
public function tick()
{
if ($this->tickFunction === null) {
return;
}
$tickFunction = $this->tickFunction;
$tickFunction($this);
}
}

View File

@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* A selection of custom filters.
*/
class CustomFilters
{
/**
* Sort an array by key.
*
* @param array $input
*
* @return array
*/
public static function sort_key(array $input)
{
ksort($input);
return $input;
}
}

View File

@@ -0,0 +1,161 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
use Liquid\Exception\RenderException;
/**
* Base class for blocks that make logical decisions.
*/
class Decision extends AbstractBlock
{
/**
* The current left variable to compare
*
* @var string
*/
public $left;
/**
* The current right variable to compare
*
* @var string
*/
public $right;
/**
* Returns a string value of an array for comparisons
*
* @param mixed $value
*
* @throws \Liquid\Exception\RenderException
* @return string
*/
private function stringValue($value)
{
// Objects should have a __toString method to get a value to compare to
if (is_object($value)) {
if (method_exists($value, '__toString')) {
return (string) $value;
}
if ($value instanceof \Generator) {
return (string) $value->valid();
}
// toLiquid is handled in Context::variable
$class = get_class($value);
throw new RenderException("Value of type $class has no `toLiquid` nor `__toString` methods");
}
// Arrays simply return true
if (is_array($value)) {
return $value;
}
return $value;
}
/**
* Check to see if to variables are equal in a given context
*
* @param string $left
* @param string $right
* @param Context $context
*
* @return bool
*/
protected function equalVariables($left, $right, Context $context)
{
$left = $this->stringValue($context->get($left));
$right = $this->stringValue($context->get($right));
return ($left == $right);
}
/**
* Interpret a comparison
*
* @param string $left
* @param string $right
* @param string $op
* @param Context $context
*
* @throws \Liquid\Exception\RenderException
* @return bool
*/
protected function interpretCondition($left, $right, $op, Context $context)
{
if (is_null($op)) {
$value = $this->stringValue($context->get($left));
return $value;
}
// values of 'empty' have a special meaning in array comparisons
if ($right == 'empty' && is_array($context->get($left))) {
$left = count($context->get($left));
$right = 0;
} elseif ($left == 'empty' && is_array($context->get($right))) {
$right = count($context->get($right));
$left = 0;
} else {
$left = $context->get($left);
$right = $context->get($right);
$left = $this->stringValue($left);
$right = $this->stringValue($right);
}
// special rules for null values
if (is_null($left) || is_null($right)) {
// null == null returns true
if ($op == '==' && is_null($left) && is_null($right)) {
return true;
}
// null != anything other than null return true
if ($op == '!=' && (!is_null($left) || !is_null($right))) {
return true;
}
// everything else, return false;
return false;
}
// regular rules
switch ($op) {
case '==':
return ($left == $right);
case '!=':
return ($left != $right);
case '>':
return ($left > $right);
case '<':
return ($left < $right);
case '>=':
return ($left >= $right);
case '<=':
return ($left <= $right);
case 'contains':
return is_array($left) ? in_array($right, $left) : (strpos($left, $right) !== false);
default:
throw new RenderException("Error in tag '" . $this->name() . "' - Unknown operator $op");
}
}
}

View File

@@ -0,0 +1,95 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
use Liquid\Tag\TagInclude;
use Liquid\Tag\TagExtends;
use Liquid\Tag\TagBlock;
/**
* This class represents the entire template document.
*/
class Document extends AbstractBlock
{
/**
* Constructor.
*
* @param array $tokens
* @param FileSystem $fileSystem
*/
public function __construct(array &$tokens, FileSystem $fileSystem = null)
{
$this->fileSystem = $fileSystem;
$this->parse($tokens);
}
/**
* Check for cached includes; if there are - do not use cache
*
* @see \Liquid\Tag\TagInclude::hasIncludes()
* @see \Liquid\Tag\TagExtends::hasIncludes()
* @return bool if need to discard cache
*/
public function hasIncludes()
{
$seenExtends = false;
$seenBlock = false;
foreach ($this->nodelist as $token) {
if ($token instanceof TagExtends) {
$seenExtends = true;
} elseif ($token instanceof TagBlock) {
$seenBlock = true;
}
}
/*
* We try to keep the base templates in cache (that not extend anything).
*
* At the same time if we re-render all other blocks we see, we avoid most
* if not all related caching quirks. This may be suboptimal.
*/
if ($seenBlock && !$seenExtends) {
return true;
}
foreach ($this->nodelist as $token) {
// check any of the tokens for includes
if ($token instanceof TagInclude && $token->hasIncludes()) {
return true;
}
if ($token instanceof TagExtends && $token->hasIncludes()) {
return true;
}
}
return false;
}
/**
* There isn't a real delimiter
*
* @return string
*/
protected function blockDelimiter()
{
return '';
}
/**
* Document blocks don't need to be terminated since they are not actually opened
*/
protected function assertMissingDelimitation()
{
}
}

View File

@@ -0,0 +1,107 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* A drop in liquid is a class which allows you to to export DOM like things to liquid.
* Methods of drops are callable.
* The main use for liquid drops is the implement lazy loaded objects.
* If you would like to make data available to the web designers which you don't want loaded unless needed then
* a drop is a great way to do that
*
* Example:
*
* class ProductDrop extends LiquidDrop {
* public function topSales() {
* Products::find('all', array('order' => 'sales', 'limit' => 10 ));
* }
* }
*
* tmpl = Liquid::Template.parse( ' {% for product in product.top_sales %} {{ product.name }} {%endfor%} ' )
* tmpl.render('product' => ProductDrop.new ) // will invoke topSales query.
*
* Your drop can either implement the methods sans any parameters or implement the beforeMethod(name) method which is a
* catch all.
*/
abstract class Drop
{
/**
* @var Context
*/
protected $context;
/**
* Catch all method that is invoked before a specific method
*
* @param string $method
*
* @return null
*/
protected function beforeMethod($method)
{
return null;
}
/**
* @param Context $context
*/
public function setContext(Context $context)
{
$this->context = $context;
}
/**
* Invoke a specific method
*
* @param string $method
*
* @return mixed
*/
public function invokeDrop($method)
{
$result = $this->beforeMethod($method);
if (is_null($result) && is_callable(array($this, $method))) {
$result = $this->$method();
}
return $result;
}
/**
* Returns true if the drop supports the given method
*
* @param string $name
*
* @return bool
*/
public function hasKey($name)
{
return true;
}
/**
* @return Drop
*/
public function toLiquid()
{
return $this;
}
/**
* @return string
*/
public function __toString()
{
return get_class($this);
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Exception;
use Liquid\LiquidException;
/**
* CacheException class.
*/
class CacheException extends LiquidException
{
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Exception;
use Liquid\LiquidException;
/**
* FilesystemException class.
*/
class FilesystemException extends LiquidException
{
}

View File

@@ -0,0 +1,22 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Exception;
use Liquid\Exception\ParseException;
/**
* Class MissingFilesystemException
* @package Liquid\Exception
*/
class MissingFilesystemException extends ParseException
{
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Exception;
use Liquid\Exception\FilesystemException;
/**
* NotFoundException class.
*/
class NotFoundException extends FilesystemException
{
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Exception;
use Liquid\LiquidException;
/**
* ParseException class.
*/
class ParseException extends LiquidException
{
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Exception;
use Liquid\LiquidException;
/**
* RenderException class.
*/
class RenderException extends LiquidException
{
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Exception;
use Liquid\LiquidException;
/**
* WrongArgumentException class.
*/
class WrongArgumentException extends LiquidException
{
}

View File

@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* A Liquid file system is way to let your templates retrieve other templates for use with the include tag.
*
* You can implement subclasses that retrieve templates from the database, from the file system using a different
* path structure, you can provide them as hard-coded inline strings, or any manner that you see fit.
*
* You can add additional instance variables, arguments, or methods as needed.
*/
interface FileSystem
{
/**
* Retrieve a template file.
*
* @param string $templatePath
*
* @return string
*/
public function readTemplateFile($templatePath);
}

View File

@@ -0,0 +1,110 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\FileSystem;
use Liquid\Exception\NotFoundException;
use Liquid\Exception\ParseException;
use Liquid\FileSystem;
use Liquid\Regexp;
use Liquid\Liquid;
/**
* This implements an abstract file system which retrieves template files named in a manner similar to Rails partials,
* ie. with the template name prefixed with an underscore. The extension ".liquid" is also added.
*
* For security reasons, template paths are only allowed to contain letters, numbers, and underscore.
*/
class Local implements FileSystem
{
/**
* The root path
*
* @var string
*/
private $root;
/**
* Constructor
*
* @param string $root The root path for templates
* @throws \Liquid\Exception\NotFoundException
*/
public function __construct($root)
{
// since root path can only be set from constructor, we check it once right here
if (!empty($root)) {
$realRoot = realpath($root);
if ($realRoot === false) {
throw new NotFoundException("Root path could not be found: '$root'");
}
$root = $realRoot;
}
$this->root = $root;
}
/**
* Retrieve a template file
*
* @param string $templatePath
*
* @return string template content
*/
public function readTemplateFile($templatePath)
{
return file_get_contents($this->fullPath($templatePath));
}
/**
* Resolves a given path to a full template file path, making sure it's valid
*
* @param string $templatePath
*
* @throws \Liquid\Exception\ParseException
* @throws \Liquid\Exception\NotFoundException
* @return string
*/
public function fullPath($templatePath)
{
if (empty($templatePath)) {
throw new ParseException("Empty template name");
}
$nameRegex = Liquid::get('INCLUDE_ALLOW_EXT')
? new Regexp('/^[^.\/][a-zA-Z0-9_\.\/-]+$/')
: new Regexp('/^[^.\/][a-zA-Z0-9_\/-]+$/');
if (!$nameRegex->match($templatePath)) {
throw new ParseException("Illegal template name '$templatePath'");
}
$templateDir = dirname($templatePath);
$templateFile = basename($templatePath);
if (!Liquid::get('INCLUDE_ALLOW_EXT')) {
$templateFile = Liquid::get('INCLUDE_PREFIX') . $templateFile . '.' . Liquid::get('INCLUDE_SUFFIX');
}
$fullPath = join(DIRECTORY_SEPARATOR, array($this->root, $templateDir, $templateFile));
$realFullPath = realpath($fullPath);
if ($realFullPath === false) {
throw new NotFoundException("File not found: $fullPath");
}
if (strpos($realFullPath, $this->root) !== 0) {
throw new NotFoundException("Illegal template full path: {$realFullPath} not under {$this->root}");
}
return $realFullPath;
}
}

View File

@@ -0,0 +1,64 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\FileSystem;
use Liquid\Exception\FilesystemException;
use Liquid\FileSystem;
/**
* This implements a virtual file system with actual code used to find files injected from outside thus achieving inversion of control.
*/
class Virtual implements FileSystem
{
/**
* @var callable
*/
private $callback;
/**
* Constructor
*
* @param callable $callback Callback is responsible for providing content of requested templates. Should return template's text.
* @throws \Liquid\Exception\FilesystemException
*/
public function __construct($callback)
{
// Since a callback can only be set from the constructor, we check it once right here.
if (!is_callable($callback)) {
throw new FilesystemException("Not a callback provided");
}
$this->callback = $callback;
}
/**
* Retrieve a template file
*
* @param string $templatePath
*
* @return string template content
*/
public function readTemplateFile($templatePath)
{
return call_user_func($this->callback, $templatePath);
}
public function __sleep()
{
// we cannot serialize a closure
if ($this->callback instanceof \Closure) {
throw new FilesystemException("Virtual file system with a Closure as a callback cannot be used with a serializing cache");
}
return array_keys(get_object_vars($this));
}
}

View File

@@ -0,0 +1,153 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
use Liquid\Exception\WrongArgumentException;
/**
* The filter bank is where all registered filters are stored, and where filter invocation is handled
* it supports a variety of different filter types; objects, class, and simple methods.
*/
class Filterbank
{
/**
* The registered filter objects
*
* @var array
*/
private $filters;
/**
* A map of all filters and the class that contain them (in the case of methods)
*
* @var array
*/
private $methodMap;
/**
* Reference to the current context object
*
* @var Context
*/
private $context;
/**
* Constructor
*
* @param $context
*/
public function __construct(Context $context)
{
$this->context = $context;
$this->addFilter(\Liquid\StandardFilters::class);
$this->addFilter(\Liquid\CustomFilters::class);
}
/**
* Adds a filter to the bank
*
* @param mixed $filter Can either be an object, the name of a class (in which case the
* filters will be called statically) or the name of a function.
*
* @throws \Liquid\Exception\WrongArgumentException
* @return bool
*/
public function addFilter($filter, callable $callback = null)
{
// If it is a callback, save it as it is
if (is_string($filter) && $callback) {
$this->methodMap[$filter] = $callback;
return true;
}
// If the filter is a class, register all its static methods
if (is_string($filter) && class_exists($filter)) {
$reflection = new \ReflectionClass($filter);
foreach ($reflection->getMethods(\ReflectionMethod::IS_STATIC) as $method) {
$this->methodMap[$method->name] = $method->class;
}
return true;
}
// If it's a global function, register it simply
if (is_string($filter) && function_exists($filter)) {
$this->methodMap[$filter] = false;
return true;
}
// If it isn't an object an isn't a string either, it's a bad parameter
if (!is_object($filter)) {
throw new WrongArgumentException("Parameter passed to addFilter must be an object or a string");
}
// If the passed filter was an object, store the object for future reference.
$filter->context = $this->context;
$className = get_class($filter);
$this->filters[$className] = $filter;
// Then register all public static and not methods as filters
foreach (get_class_methods($filter) as $method) {
if (strtolower($method) === '__construct') {
continue;
}
$this->methodMap[$method] = $className;
}
return true;
}
/**
* Invokes the filter with the given name
*
* @param string $name The name of the filter
* @param string $value The value to filter
* @param array $args The additional arguments for the filter
*
* @return string
*/
public function invoke($name, $value, array $args = array())
{
// workaround for a single standard filter being a reserved keyword - we can't use overloading for static calls
if ($name == 'default') {
$name = '_default';
}
array_unshift($args, $value);
// Consult the mapping
if (!isset($this->methodMap[$name])) {
return $value;
}
$class = $this->methodMap[$name];
// If we have a callback
if (is_callable($class)) {
return call_user_func_array($class, $args);
}
// If we have a registered object for the class, use that instead
if (isset($this->filters[$class])) {
$class = $this->filters[$class];
}
// If we're calling a function
if ($class === false) {
return call_user_func_array($name, $args);
}
// Call a class or an instance method
return call_user_func_array(array($class, $name), $args);
}
}

View File

@@ -0,0 +1,170 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* Liquid for PHP.
*/
class Liquid
{
/**
* We cannot make settings constants, because we cannot create compound
* constants in PHP (before 5.6).
*
* @var array configuration array
*/
public static $config = array(
// The method is called on objects when resolving variables to see
// if a given property exists.
'HAS_PROPERTY_METHOD' => 'field_exists',
// This method is called on object when resolving variables when
// a given property exists.
'GET_PROPERTY_METHOD' => 'get',
// Separator between filters.
'FILTER_SEPARATOR' => '\|',
// Separator for arguments.
'ARGUMENT_SEPARATOR' => ',',
// Separator for argument names and values.
'FILTER_ARGUMENT_SEPARATOR' => ':',
// Separator for variable attributes.
'VARIABLE_ATTRIBUTE_SEPARATOR' => '.',
// Allow template names with extension in include and extends tags.
'INCLUDE_ALLOW_EXT' => false,
// Suffix for include files.
'INCLUDE_SUFFIX' => 'liquid',
// Prefix for include files.
'INCLUDE_PREFIX' => '_',
// Whitespace control.
'WHITESPACE_CONTROL' => '-',
// Tag start.
'TAG_START' => '{%',
// Tag end.
'TAG_END' => '%}',
// Variable start.
'VARIABLE_START' => '{{',
// Variable end.
'VARIABLE_END' => '}}',
// Variable name.
'VARIABLE_NAME' => '[a-zA-Z_][a-zA-Z_0-9.-]*',
'QUOTED_STRING' => '(?:"[^"]*"|\'[^\']*\')',
'QUOTED_STRING_FILTER_ARGUMENT' => '"[^"]*"|\'[^\']*\'',
// Automatically escape any variables unless told otherwise by a "raw" filter
'ESCAPE_BY_DEFAULT' => false,
// The name of the key to use when building pagination query strings e.g. ?page=1
'PAGINATION_REQUEST_KEY' => 'page',
// The name of the context key used to denote the current page number
'PAGINATION_CONTEXT_KEY' => 'page',
// Whenever variables from $_SERVER should be directly available to templates
'EXPOSE_SERVER' => false,
// $_SERVER variables whitelist - exposed even when EXPOSE_SERVER is false
'SERVER_SUPERGLOBAL_WHITELIST' => [
'HTTP_ACCEPT',
'HTTP_ACCEPT_CHARSET',
'HTTP_ACCEPT_ENCODING',
'HTTP_ACCEPT_LANGUAGE',
'HTTP_CONNECTION',
'HTTP_HOST',
'HTTP_REFERER',
'HTTP_USER_AGENT',
'HTTPS',
'REQUEST_METHOD',
'REQUEST_URI',
'SERVER_NAME',
],
);
/**
* Get a configuration setting.
*
* @param string $key setting key
*
* @return string
*/
public static function get($key)
{
// backward compatibility
if ($key === 'ALLOWED_VARIABLE_CHARS') {
return substr(self::$config['VARIABLE_NAME'], 0, -1);
}
if (array_key_exists($key, self::$config)) {
return self::$config[$key];
}
// This case is needed for compound settings
switch ($key) {
case 'QUOTED_FRAGMENT':
return '(?:' . self::get('QUOTED_STRING') . '|(?:[^\s,\|\'"]|' . self::get('QUOTED_STRING') . ')+)';
case 'TAG_ATTRIBUTES':
return '/(\w+)\s*\:\s*(' . self::get('QUOTED_FRAGMENT') . ')/';
case 'TOKENIZATION_REGEXP':
return '/(' . self::$config['TAG_START'] . '.*?' . self::$config['TAG_END'] . '|' . self::$config['VARIABLE_START'] . '.*?' . self::$config['VARIABLE_END'] . ')/s';
default:
return null;
}
}
/**
* Changes/creates a setting.
*
* @param string $key
* @param string $value
*/
public static function set($key, $value)
{
// backward compatibility
if ($key === 'ALLOWED_VARIABLE_CHARS') {
$key = 'VARIABLE_NAME';
$value .= '+';
}
self::$config[$key] = $value;
}
/**
* Flatten a multidimensional array into a single array. Does not maintain keys.
*
* @param array $array
*
* @return array
*/
public static function arrayFlatten($array)
{
$return = array();
foreach ($array as $element) {
if (is_array($element)) {
$return = array_merge($return, self::arrayFlatten($element));
} else {
$return[] = $element;
}
}
return $return;
}
}

View File

@@ -0,0 +1,19 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* LiquidException class.
*/
class LiquidException extends \Exception
{
}

View File

@@ -0,0 +1,19 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* @deprecated Left for backward compatibility reasons. Use \Liquid\FileSystem\Local instead.
*/
class LocalFileSystem extends \Liquid\FileSystem\Local
{
}

View File

@@ -0,0 +1,134 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
/**
* A support class for regular expressions and
* non liquid specific support classes and functions.
*/
class Regexp
{
/**
* The regexp pattern
*
* @var string
*/
private $pattern;
/**
* The matches from the last method called
*
* @var array;
*/
public $matches;
/**
* Constructor
*
* @param string $pattern
*
* @return Regexp
*/
public function __construct($pattern)
{
$this->pattern = (substr($pattern, 0, 1) != '/')
? '/' . $this->quote($pattern) . '/'
: $pattern;
}
/**
* Quotes regular expression characters
*
* @param string $string
*
* @return string
*/
public function quote($string)
{
return preg_quote($string, '/');
}
/**
* Returns an array of matches for the string in the same way as Ruby's scan method
*
* @param string $string
*
* @return array
*/
public function scan($string)
{
preg_match_all($this->pattern, $string, $matches);
if (count($matches) == 1) {
return $matches[0];
}
array_shift($matches);
$result = array();
foreach ($matches as $matchKey => $subMatches) {
foreach ($subMatches as $subMatchKey => $subMatch) {
$result[$subMatchKey][$matchKey] = $subMatch;
}
}
return $result;
}
/**
* Matches the given string. Only matches once.
*
* @param string $string
*
* @return int 1 if there was a match, 0 if there wasn't
*/
public function match($string)
{
return preg_match($this->pattern, $string, $this->matches);
}
/**
* Matches the given string. Matches all.
*
* @param string $string
*
* @return int The number of matches
*/
public function matchAll($string)
{
return preg_match_all($this->pattern, $string, $this->matches);
}
/**
* Splits the given string
*
* @param string $string
* @param int $limit Limits the amount of results returned
*
* @return array
*/
public function split($string, $limit = -1)
{
return preg_split($this->pattern, $string, $limit);
}
/**
* Returns the original pattern primarily for debugging purposes
*
* @return string
*/
public function __toString()
{
return $this->pattern;
}
}

View File

@@ -0,0 +1,727 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid;
use Liquid\Exception\RenderException;
/**
* A selection of standard filters.
*/
class StandardFilters
{
/**
* Add one string to another
*
* @param string $input
* @param string $string
*
* @return string
*/
public static function append($input, $string)
{
return $input . $string;
}
/**
* Capitalize words in the input sentence
*
* @param string $input
*
* @return string
*/
public static function capitalize($input)
{
return preg_replace_callback("/(^|[^\p{L}'])([\p{Ll}])/u", function ($matches) {
$first_char = mb_substr($matches[2], 0, 1);
return $matches[1] . mb_strtoupper($first_char) . mb_substr($matches[2], 1);
}, ucwords($input));
}
/**
* @param mixed $input number
*
* @return int
*/
public static function ceil($input)
{
return (int) ceil((float)$input);
}
/**
* Formats a date using strftime
*
* @param mixed $input
* @param string $format
*
* @return string
*/
public static function date($input, $format)
{
if (!is_numeric($input)) {
$input = strtotime($input);
}
if ($format == 'r') {
return date($format, $input);
}
return strftime($format, $input);
}
/**
* Default
*
* @param string $input
* @param string $default_value
*
* @return string
*/
public static function _default($input, $default_value)
{
$isBlank = $input == '' || $input === false || $input === null;
return $isBlank ? $default_value : $input;
}
/**
* division
*
* @param float $input
* @param float $operand
*
* @return float
*/
public static function divided_by($input, $operand)
{
return (float)$input / (float)$operand;
}
/**
* Convert an input to lowercase
*
* @param string $input
*
* @return string
*/
public static function downcase($input)
{
return is_string($input) ? mb_strtolower($input) : $input;
}
/**
* Pseudo-filter: negates auto-added escape filter
*
* @param string $input
*
* @return string
*/
public static function raw($input)
{
return $input;
}
/**
* Escape a string
*
* @param string $input
*
* @return string
*/
public static function escape($input)
{
// Arrays are taken care down the stack with an error
if (is_array($input)) {
return $input;
}
return htmlentities($input, ENT_QUOTES);
}
/**
* Escape a string once, keeping all previous HTML entities intact
*
* @param string $input
*
* @return string
*/
public static function escape_once($input)
{
// Arrays are taken care down the stack with an error
if (is_array($input)) {
return $input;
}
return htmlentities($input, ENT_QUOTES, null, false);
}
/**
* Returns the first element of an array
*
* @param array|\Iterator $input
*
* @return mixed
*/
public static function first($input)
{
if ($input instanceof \Iterator) {
$input->rewind();
return $input->current();
}
return is_array($input) ? reset($input) : $input;
}
/**
* @param mixed $input number
*
* @return int
*/
public static function floor($input)
{
return (int) floor((float)$input);
}
/**
* Joins elements of an array with a given character between them
*
* @param array|\Traversable $input
* @param string $glue
*
* @return string
*/
public static function join($input, $glue = ' ')
{
if ($input instanceof \Traversable) {
$str = '';
foreach ($input as $elem) {
if ($str) {
$str .= $glue;
}
$str .= $elem;
}
return $str;
}
return is_array($input) ? implode($glue, $input) : $input;
}
/**
* Returns the last element of an array
*
* @param array|\Traversable $input
*
* @return mixed
*/
public static function last($input)
{
if ($input instanceof \Traversable) {
$last = null;
foreach ($input as $elem) {
$last = $elem;
}
return $last;
}
return is_array($input) ? end($input) : $input;
}
/**
* @param string $input
*
* @return string
*/
public static function lstrip($input)
{
return ltrim($input);
}
/**
* Map/collect on a given property
*
* @param array|\Traversable $input
* @param string $property
*
* @return string
*/
public static function map($input, $property)
{
if ($input instanceof \Traversable) {
$input = iterator_to_array($input);
}
if (!is_array($input)) {
return $input;
}
return array_map(function ($elem) use ($property) {
if (is_callable($elem)) {
return $elem();
} elseif (is_array($elem) && array_key_exists($property, $elem)) {
return $elem[$property];
}
return null;
}, $input);
}
/**
* subtraction
*
* @param float $input
* @param float $operand
*
* @return float
*/
public static function minus($input, $operand)
{
return (float)$input - (float)$operand;
}
/**
* modulo
*
* @param float $input
* @param float $operand
*
* @return float
*/
public static function modulo($input, $operand)
{
return fmod((float)$input, (float)$operand);
}
/**
* Replace each newline (\n) with html break
*
* @param string $input
*
* @return string
*/
public static function newline_to_br($input)
{
return is_string($input) ? str_replace("\n", "<br />\n", $input) : $input;
}
/**
* addition
*
* @param float $input
* @param float $operand
*
* @return float
*/
public static function plus($input, $operand)
{
return (float)$input + (float)$operand;
}
/**
* Prepend a string to another
*
* @param string $input
* @param string $string
*
* @return string
*/
public static function prepend($input, $string)
{
return $string . $input;
}
/**
* Remove a substring
*
* @param string $input
* @param string $string
*
* @return string
*/
public static function remove($input, $string)
{
return str_replace($string, '', $input);
}
/**
* Remove the first occurrences of a substring
*
* @param string $input
* @param string $string
*
* @return string
*/
public static function remove_first($input, $string)
{
if (($pos = strpos($input, $string)) !== false) {
$input = substr_replace($input, '', $pos, strlen($string));
}
return $input;
}
/**
* Replace occurrences of a string with another
*
* @param string $input
* @param string $string
* @param string $replacement
*
* @return string
*/
public static function replace($input, $string, $replacement = '')
{
return str_replace($string, $replacement, $input);
}
/**
* Replace the first occurrences of a string with another
*
* @param string $input
* @param string $string
* @param string $replacement
*
* @return string
*/
public static function replace_first($input, $string, $replacement = '')
{
if (($pos = strpos($input, $string)) !== false) {
$input = substr_replace($input, $replacement, $pos, strlen($string));
}
return $input;
}
/**
* Reverse the elements of an array
*
* @param array|\Traversable $input
*
* @return array
*/
public static function reverse($input)
{
if ($input instanceof \Traversable) {
$input = iterator_to_array($input);
}
return array_reverse($input);
}
/**
* Round a number
*
* @param float $input
* @param int $n precision
*
* @return float
*/
public static function round($input, $n = 0)
{
return round((float)$input, (int)$n);
}
/**
* @param string $input
*
* @return string
*/
public static function rstrip($input)
{
return rtrim($input);
}
/**
* Return the size of an array or of an string
*
* @param mixed $input
* @throws RenderException
* @return int
*/
public static function size($input)
{
if ($input instanceof \Iterator) {
return iterator_count($input);
}
if (is_array($input)) {
return count($input);
}
if (is_object($input)) {
if (method_exists($input, 'size')) {
return $input->size();
}
if (!method_exists($input, '__toString')) {
$class = get_class($input);
throw new RenderException("Size of $class cannot be estimated: it has no method 'size' nor can be converted to a string");
}
}
// only plain values and stringable objects left at this point
return strlen($input);
}
/**
* @param array|\Iterator|string $input
* @param int $offset
* @param int $length
*
* @return array|\Iterator|string
*/
public static function slice($input, $offset, $length = null)
{
if ($input instanceof \Iterator) {
$input = iterator_to_array($input);
}
if (is_array($input)) {
$input = array_slice($input, $offset, $length);
} elseif (is_string($input)) {
$input = mb_substr($input, $offset, $length);
}
return $input;
}
/**
* Sort the elements of an array
*
* @param array|\Traversable $input
* @param string $property use this property of an array element
*
* @return array
*/
public static function sort($input, $property = null)
{
if ($input instanceof \Traversable) {
$input = iterator_to_array($input);
}
if ($property === null) {
asort($input);
} else {
$first = reset($input);
if ($first !== false && is_array($first) && array_key_exists($property, $first)) {
uasort($input, function ($a, $b) use ($property) {
if ($a[$property] == $b[$property]) {
return 0;
}
return $a[$property] < $b[$property] ? -1 : 1;
});
}
}
return $input;
}
/**
* Explicit string conversion.
*
* @param mixed $input
*
* @return string
*/
public static function string($input)
{
return strval($input);
}
/**
* Split input string into an array of substrings separated by given pattern.
*
* @param string $input
* @param string $pattern
*
* @return array
*/
public static function split($input, $pattern)
{
if ($input === '' || $input === null) {
return [];
}
return explode($pattern, $input);
}
/**
* @param string $input
*
* @return string
*/
public static function strip($input)
{
return trim($input);
}
/**
* Removes html tags from text
*
* @param string $input
*
* @return string
*/
public static function strip_html($input)
{
return is_string($input) ? strip_tags($input) : $input;
}
/**
* Strip all newlines (\n, \r) from string
*
* @param string $input
*
* @return string
*/
public static function strip_newlines($input)
{
return is_string($input) ? str_replace(array(
"\n", "\r"
), '', $input) : $input;
}
/**
* multiplication
*
* @param float $input
* @param float $operand
*
* @return float
*/
public static function times($input, $operand)
{
return (float)$input * (float)$operand;
}
/**
* Truncate a string down to x characters
*
* @param string $input
* @param int $characters
* @param string $ending string to append if truncated
*
* @return string
*/
public static function truncate($input, $characters = 100, $ending = '...')
{
if (is_string($input) || is_numeric($input)) {
if (strlen($input) > $characters) {
return mb_substr($input, 0, $characters) . $ending;
}
}
return $input;
}
/**
* Truncate string down to x words
*
* @param string $input
* @param int $words
* @param string $ending string to append if truncated
*
* @return string
*/
public static function truncatewords($input, $words = 3, $ending = '...')
{
if (is_string($input)) {
$wordlist = explode(" ", $input);
if (count($wordlist) > $words) {
return implode(" ", array_slice($wordlist, 0, $words)) . $ending;
}
}
return $input;
}
/**
* Remove duplicate elements from an array
*
* @param array|\Traversable $input
*
* @return array
*/
public static function uniq($input)
{
if ($input instanceof \Traversable) {
$input = iterator_to_array($input);
}
return array_unique($input);
}
/**
* Convert an input to uppercase
*
* @param string $input
*
* @return string
*/
public static function upcase($input)
{
return is_string($input) ? mb_strtoupper($input) : $input;
}
/**
* URL encodes a string
*
* @param string $input
*
* @return string
*/
public static function url_encode($input)
{
return urlencode($input);
}
/**
* Decodes a URL-encoded string
*
* @param string $input
*
* @return string
*/
public static function url_decode($input)
{
return urldecode($input);
}
}

View File

@@ -0,0 +1,76 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Tag;
use Liquid\AbstractTag;
use Liquid\Exception\ParseException;
use Liquid\Liquid;
use Liquid\FileSystem;
use Liquid\Regexp;
use Liquid\Context;
use Liquid\Variable;
/**
* Performs an assignment of one variable to another
*
* Example:
*
* {% assign var = var %}
* {% assign var = "hello" | upcase %}
*/
class TagAssign extends AbstractTag
{
/**
* @var string The variable to assign from
*/
private $from;
/**
* @var string The variable to assign to
*/
private $to;
/**
* Constructor
*
* @param string $markup
* @param array $tokens
* @param FileSystem $fileSystem
*
* @throws \Liquid\Exception\ParseException
*/
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
{
$syntaxRegexp = new Regexp('/(\w+)\s*=\s*(.*)\s*/');
if ($syntaxRegexp->match($markup)) {
$this->to = $syntaxRegexp->matches[1];
$this->from = new Variable($syntaxRegexp->matches[2]);
} else {
throw new ParseException("Syntax Error in 'assign' - Valid syntax: assign [var] = [source]");
}
}
/**
* Renders the tag
*
* @param Context $context
*
* @return string|void
*/
public function render(Context $context)
{
$output = $this->from->render($context);
$context->set($this->to, $output, true);
}
}

View File

@@ -0,0 +1,56 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Tag;
use Liquid\AbstractBlock;
use Liquid\Exception\ParseException;
use Liquid\FileSystem;
use Liquid\Regexp;
/**
* Marks a section of a template as being reusable.
*
* Example:
*
* {% block foo %} bar {% endblock %}
*/
class TagBlock extends AbstractBlock
{
/**
* The variable to assign to
*
* @var string
*/
private $block;
/**
* Constructor
*
* @param string $markup
* @param array $tokens
* @param FileSystem $fileSystem
*
* @throws \Liquid\Exception\ParseException
* @return \Liquid\Tag\TagBlock
*/
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
{
$syntaxRegexp = new Regexp('/(\w+)/');
if ($syntaxRegexp->match($markup)) {
$this->block = $syntaxRegexp->matches[1];
parent::__construct($markup, $tokens, $fileSystem);
} else {
throw new ParseException("Syntax Error in 'block' - Valid syntax: block [name]");
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Tag;
use Liquid\AbstractTag;
use Liquid\Context;
/**
* Break iteration of the current loop
*
* Example:
*
* {% for i in (1..5) %}
* {% if i == 4 %}
* {% break %}
* {% endif %}
* {{ i }}
* {% endfor %}
*/
class TagBreak extends AbstractTag
{
/**
* Renders the tag
*
* @param Context $context
*
* @return string|void
*/
public function render(Context $context)
{
$context->registers['break'] = true;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Tag;
use Liquid\AbstractBlock;
use Liquid\Context;
use Liquid\Exception\ParseException;
use Liquid\FileSystem;
use Liquid\Regexp;
/**
* Captures the output inside a block and assigns it to a variable
*
* Example:
*
* {% capture foo %} bar {% endcapture %}
*/
class TagCapture extends AbstractBlock
{
/**
* The variable to assign to
*
* @var string
*/
private $to;
/**
* Constructor
*
* @param string $markup
* @param array $tokens
* @param FileSystem $fileSystem
*
* @throws \Liquid\Exception\ParseException
*/
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
{
$syntaxRegexp = new Regexp('/(\w+)/');
if ($syntaxRegexp->match($markup)) {
$this->to = $syntaxRegexp->matches[1];
parent::__construct($markup, $tokens, $fileSystem);
} else {
throw new ParseException("Syntax Error in 'capture' - Valid syntax: capture [var] [value]");
}
}
/**
* Renders the block
*
* @param Context $context
*
* @return string
*/
public function render(Context $context)
{
$output = parent::render($context);
$context->set($this->to, $output, true);
return '';
}
}

View File

@@ -0,0 +1,171 @@
<?php
/*
* This file is part of the Liquid package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Liquid
*/
namespace Liquid\Tag;
use Liquid\Decision;
use Liquid\Context;
use Liquid\Exception\ParseException;
use Liquid\Liquid;
use Liquid\FileSystem;
use Liquid\Regexp;
/**
* A switch statement
*
* Example:
*
* {% case condition %}{% when foo %} foo {% else %} bar {% endcase %}
*/
class TagCase extends Decision
{
/**
* Stack of nodelists
*
* @var array
*/
public $nodelists;
/**
* The nodelist for the else (default) nodelist
*
* @var array
*/
public $elseNodelist;
/**
* The left value to compare
*
* @var string
*/
public $left;
/**
* The current right value to compare
*
* @var mixed
*/
public $right;
/**
* Constructor
*
* @param string $markup
* @param array $tokens
* @param FileSystem $fileSystem
*
* @throws \Liquid\Exception\ParseException
*/
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
{
$this->nodelists = array();
$this->elseNodelist = array();
parent::__construct($markup, $tokens, $fileSystem);
$syntaxRegexp = new Regexp('/' . Liquid::get('QUOTED_FRAGMENT') . '/');
if ($syntaxRegexp->match($markup)) {
$this->left = $syntaxRegexp->matches[0];
} else {
throw new ParseException("Syntax Error in tag 'case' - Valid syntax: case [condition]"); // harry
}
}
/**
* Pushes the last nodelist onto the stack
*/
public function endTag()
{
$this->pushNodelist();
}
/**
* Unknown tag handler
*
* @param string $tag
* @param string $params
* @param array $tokens
*
* @throws \Liquid\Exception\ParseException
*/
public function unknownTag($tag, $params, array $tokens)
{
$whenSyntaxRegexp = new Regexp('/' . Liquid::get('QUOTED_FRAGMENT') . '/');
switch ($tag) {
case 'when':
// push the current nodelist onto the stack and prepare for a new one
if ($whenSyntaxRegexp->match($params)) {
$this->pushNodelist();
$this->right = $whenSyntaxRegexp->matches[0];
$this->nodelist = array();
} else {
throw new ParseException("Syntax Error in tag 'case' - Valid when condition: when [condition]"); // harry
}
break;
case 'else':
// push the last nodelist onto the stack and prepare to receive the else nodes
$this->pushNodelist();
$this->right = null;
$this->elseNodelist = &$this->nodelist;
$this->nodelist = array();
break;
default:
parent::unknownTag($tag, $params, $tokens);
}
}
/**
* Pushes the current right value and nodelist into the nodelist stack
*/
public function pushNodelist()
{
if (!is_null($this->right)) {
$this->nodelists[] = array($this->right, $this->nodelist);
}
}
/**
* Renders the node
*
* @param Context $context
*
* @return string
*/
public function render(Context $context)
{
$output = ''; // array();
$runElseBlock = true;
foreach ($this->nodelists as $data) {
list($right, $nodelist) = $data;
if ($this->equalVariables($this->left, $right, $context)) {
$runElseBlock = false;
$context->push();
$output .= $this->renderAll($nodelist, $context);
$context->pop();
}
}
if ($runElseBlock) {
$context->push();
$output .= $this->renderAll($this->elseNodelist, $context);
$context->pop();
}
return $output;
}
}

Some files were not shown because too many files have changed in this diff Show More