Index: CHANGES =================================================================== --- CHANGES (revision 155344) +++ CHANGES (revision 155345) @@ -2,6 +2,9 @@ [Remove entries to the current 2.0 section below, when backported] + *) Correctly export all mod_dav public functions. + [Branko Čibej ] + Changes with Apache 2.1.3 *) core_input_filter: Move buckets to a persistent brigade instead of Index: modules/dav/main/mod_dav.h =================================================================== --- modules/dav/main/mod_dav.h (revision 155344) +++ modules/dav/main/mod_dav.h (revision 155345) @@ -464,8 +464,8 @@ } dav_lookup_result; -dav_lookup_result dav_lookup_uri(const char *uri, request_rec *r, - int must_be_absolute); +DAV_DECLARE(dav_lookup_result) dav_lookup_uri(const char *uri, request_rec *r, + int must_be_absolute); /* defines type of property info a provider is to return */ typedef enum { @@ -492,10 +492,12 @@ #define DAV_STYLE_RFC822 2 #define DAV_TIMEBUF_SIZE 30 -int dav_get_depth(request_rec *r, int def_depth); +DAV_DECLARE(int) dav_get_depth(request_rec *r, int def_depth); -int dav_validate_root(const apr_xml_doc *doc, const char *tagname); -apr_xml_elem *dav_find_child(const apr_xml_elem *elem, const char *tagname); +DAV_DECLARE(int) dav_validate_root(const apr_xml_doc *doc, + const char *tagname); +DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem, + const char *tagname); /* gather up all the CDATA into a single string */ DAV_DECLARE(const char *) dav_xml_get_cdata(const apr_xml_elem *elem, apr_pool_t *pool, @@ -631,15 +633,15 @@ (request_rec *r, const dav_resource *resource, dav_prop_insert what, apr_text_header *phdr)) -const dav_hooks_locks *dav_get_lock_hooks(request_rec *r); -const dav_hooks_propdb *dav_get_propdb_hooks(request_rec *r); -const dav_hooks_vsn *dav_get_vsn_hooks(request_rec *r); -const dav_hooks_binding *dav_get_binding_hooks(request_rec *r); -const dav_hooks_search *dav_get_search_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_locks *) dav_get_lock_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_propdb *) dav_get_propdb_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_vsn *) dav_get_vsn_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_binding *) dav_get_binding_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_search *) dav_get_search_hooks(request_rec *r); DAV_DECLARE(void) dav_register_provider(apr_pool_t *p, const char *name, const dav_provider *hooks); -const dav_provider * dav_lookup_provider(const char *name); +DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name); /* ### deprecated */ @@ -712,7 +714,8 @@ struct dav_locktoken_list *next; } dav_locktoken_list; -dav_error * dav_get_locktoken_list(request_rec *r, dav_locktoken_list **ltl); +DAV_DECLARE(dav_error *) dav_get_locktoken_list(request_rec *r, + dav_locktoken_list **ltl); /* -------------------------------------------------------------------- @@ -885,22 +888,27 @@ DAV_DECLARE(int) dav_get_liveprop_ns_index(const char *uri); /* ### docco */ -int dav_get_liveprop_ns_count(void); +DAV_DECLARE(int) dav_get_liveprop_ns_count(void); /* ### docco */ -void dav_add_all_liveprop_xmlns(apr_pool_t *p, apr_text_header *phdr); +DAV_DECLARE(void) dav_add_all_liveprop_xmlns(apr_pool_t *p, + apr_text_header *phdr); /* ** The following three functions are part of mod_dav's internal handling ** for the core WebDAV properties. They are not part of mod_dav's API. */ -int dav_core_find_liveprop(const dav_resource *resource, - const char *ns_uri, const char *name, - const dav_hooks_liveprop **hooks); -void dav_core_insert_all_liveprops(request_rec *r, - const dav_resource *resource, - dav_prop_insert what, apr_text_header *phdr); -void dav_core_register_uris(apr_pool_t *p); +DAV_DECLARE_NONSTD(int) dav_core_find_liveprop( + const dav_resource *resource, + const char *ns_uri, + const char *name, + const dav_hooks_liveprop **hooks); +DAV_DECLARE_NONSTD(void) dav_core_insert_all_liveprops( + request_rec *r, + const dav_resource *resource, + dav_prop_insert what, + apr_text_header *phdr); +DAV_DECLARE_NONSTD(void) dav_core_register_uris(apr_pool_t *p); /* @@ -1126,7 +1134,7 @@ /* Used to represent a Timeout header of "Infinity" */ #define DAV_TIMEOUT_INFINITE 0 -time_t dav_get_timeout(request_rec *r); +DAV_DECLARE(time_t) dav_get_timeout(request_rec *r); /* ** Opaque, provider-specific information for a lock database. @@ -1221,34 +1229,40 @@ } dav_lock; /* Property-related public lock functions */ -const char *dav_lock_get_activelock(request_rec *r, dav_lock *locks, - dav_buffer *pbuf); +DAV_DECLARE(const char *)dav_lock_get_activelock(request_rec *r, + dav_lock *locks, + dav_buffer *pbuf); /* LockDB-related public lock functions */ -dav_error * dav_lock_parse_lockinfo(request_rec *r, - const dav_resource *resrouce, - dav_lockdb *lockdb, - const apr_xml_doc *doc, - dav_lock **lock_request); -int dav_unlock(request_rec *r, const dav_resource *resource, - const dav_locktoken *locktoken); -dav_error * dav_add_lock(request_rec *r, const dav_resource *resource, - dav_lockdb *lockdb, dav_lock *request, - dav_response **response); -dav_error * dav_notify_created(request_rec *r, - dav_lockdb *lockdb, - const dav_resource *resource, - int resource_state, - int depth); +DAV_DECLARE(dav_error *) dav_lock_parse_lockinfo(request_rec *r, + const dav_resource *resrouce, + dav_lockdb *lockdb, + const apr_xml_doc *doc, + dav_lock **lock_request); +DAV_DECLARE(int) dav_unlock(request_rec *r, + const dav_resource *resource, + const dav_locktoken *locktoken); +DAV_DECLARE(dav_error *) dav_add_lock(request_rec *r, + const dav_resource *resource, + dav_lockdb *lockdb, dav_lock *request, + dav_response **response); +DAV_DECLARE(dav_error *) dav_notify_created(request_rec *r, + dav_lockdb *lockdb, + const dav_resource *resource, + int resource_state, + int depth); DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb, const dav_resource *resource, dav_lock **locks); -dav_error * dav_validate_request(request_rec *r, dav_resource *resource, - int depth, dav_locktoken *locktoken, - dav_response **response, int flags, - dav_lockdb *lockdb); +DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r, + dav_resource *resource, + int depth, + dav_locktoken *locktoken, + dav_response **response, + int flags, + dav_lockdb *lockdb); /* ** flags: ** 0x0F -- reserved for values @@ -1263,7 +1277,8 @@ #define DAV_VALIDATE_IS_PARENT 0x0100 /* for internal use */ /* Lock-null related public lock functions */ -int dav_get_resource_state(request_rec *r, const dav_resource *resource); +DAV_DECLARE(int) dav_get_resource_state(request_rec *r, + const dav_resource *resource); /* Lock provider hooks. Locking is optional, so there may be no * lock provider for a given repository. @@ -1484,7 +1499,7 @@ typedef struct dav_propdb dav_propdb; -dav_error *dav_open_propdb( +DAV_DECLARE(dav_error *) dav_open_propdb( request_rec *r, dav_lockdb *lockdb, const dav_resource *resource, @@ -1492,17 +1507,17 @@ apr_array_header_t *ns_xlate, dav_propdb **propdb); -void dav_close_propdb(dav_propdb *db); +DAV_DECLARE(void) dav_close_propdb(dav_propdb *db); -dav_get_props_result dav_get_props( +DAV_DECLARE(dav_get_props_result) dav_get_props( dav_propdb *db, apr_xml_doc *doc); -dav_get_props_result dav_get_allprops( +DAV_DECLARE(dav_get_props_result) dav_get_allprops( dav_propdb *db, dav_prop_insert what); -void dav_get_liveprop_supported( +DAV_DECLARE(void) dav_get_liveprop_supported( dav_propdb *propdb, const char *ns_uri, const char *propname, @@ -1567,10 +1582,10 @@ } dav_prop_ctx; -void dav_prop_validate(dav_prop_ctx *ctx); -void dav_prop_exec(dav_prop_ctx *ctx); -void dav_prop_commit(dav_prop_ctx *ctx); -void dav_prop_rollback(dav_prop_ctx *ctx); +DAV_DECLARE_NONSTD(void) dav_prop_validate(dav_prop_ctx *ctx); +DAV_DECLARE_NONSTD(void) dav_prop_exec(dav_prop_ctx *ctx); +DAV_DECLARE_NONSTD(void) dav_prop_commit(dav_prop_ctx *ctx); +DAV_DECLARE_NONSTD(void) dav_prop_rollback(dav_prop_ctx *ctx); #define DAV_PROP_CTX_HAS_ERR(dpc) ((dpc).err && (dpc).err->status >= 300) @@ -1933,9 +1948,9 @@ * If there were any headers in the request which require a Vary header * in the response, add it. */ -void dav_add_vary_header(request_rec *in_req, - request_rec *out_req, - const dav_resource *resource); +DAV_DECLARE(void) dav_add_vary_header(request_rec *in_req, + request_rec *out_req, + const dav_resource *resource); /* ** Flags specifying auto-versioning behavior, returned by @@ -1994,7 +2009,7 @@ * to restore both parent and child resources to the state they were in * before the auto-versioning operations occurred. */ -dav_error *dav_auto_checkout( +DAV_DECLARE(dav_error *) dav_auto_checkout( request_rec *r, dav_resource *resource, int parent_only, @@ -2015,7 +2030,7 @@ * was checked out (i.e. the parent_only was != 0 in the * dav_auto_checkout call). */ -dav_error *dav_auto_checkin( +DAV_DECLARE(dav_error *) dav_auto_checkin( request_rec *r, dav_resource *resource, int undo, @@ -2391,7 +2406,7 @@ */ /* fetch the "LimitXMLRequestBody" in force for this resource */ -apr_size_t dav_get_limit_xml_body(const request_rec *r); +DAV_DECLARE(apr_size_t) dav_get_limit_xml_body(const request_rec *r); typedef struct { int propid; /* live property ID */ Index: modules/dav/main/liveprop.c =================================================================== --- modules/dav/main/liveprop.c (revision 155344) +++ modules/dav/main/liveprop.c (revision 155345) @@ -58,12 +58,13 @@ return (int)apr_hash_get(dav_liveprop_uris, uri, APR_HASH_KEY_STRING); } -int dav_get_liveprop_ns_count(void) +DAV_DECLARE(int) dav_get_liveprop_ns_count(void) { return dav_liveprop_count; } -void dav_add_all_liveprop_xmlns(apr_pool_t *p, apr_text_header *phdr) +DAV_DECLARE(void) dav_add_all_liveprop_xmlns(apr_pool_t *p, + apr_text_header *phdr) { apr_hash_index_t *idx = apr_hash_first(p, dav_liveprop_uris); Index: modules/dav/main/props.c =================================================================== --- modules/dav/main/props.c (revision 155344) +++ modules/dav/main/props.c (revision 155345) @@ -514,11 +514,11 @@ return NULL; } -dav_error *dav_open_propdb(request_rec *r, dav_lockdb *lockdb, - const dav_resource *resource, - int ro, - apr_array_header_t * ns_xlate, - dav_propdb **p_propdb) +DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb, + const dav_resource *resource, + int ro, + apr_array_header_t * ns_xlate, + dav_propdb **p_propdb) { dav_propdb *propdb = apr_pcalloc(r->pool, sizeof(*propdb)); @@ -552,7 +552,7 @@ return NULL; } -void dav_close_propdb(dav_propdb *propdb) +DAV_DECLARE(void) dav_close_propdb(dav_propdb *propdb) { if (propdb->db != NULL) { (*propdb->db_hooks->close)(propdb->db); @@ -565,7 +565,8 @@ return; } -dav_get_props_result dav_get_allprops(dav_propdb *propdb, dav_prop_insert what) +DAV_DECLARE(dav_get_props_result) dav_get_allprops(dav_propdb *propdb, + dav_prop_insert what) { const dav_hooks_db *db_hooks = propdb->db_hooks; apr_text_header hdr = { 0 }; @@ -692,7 +693,8 @@ return result; } -dav_get_props_result dav_get_props(dav_propdb *propdb, apr_xml_doc *doc) +DAV_DECLARE(dav_get_props_result) dav_get_props(dav_propdb *propdb, + apr_xml_doc *doc) { const dav_hooks_db *db_hooks = propdb->db_hooks; apr_xml_elem *elem = dav_find_child(doc->root, "prop"); @@ -879,10 +881,10 @@ return result; } -void dav_get_liveprop_supported(dav_propdb *propdb, - const char *ns_uri, - const char *propname, - apr_text_header *body) +DAV_DECLARE(void) dav_get_liveprop_supported(dav_propdb *propdb, + const char *ns_uri, + const char *propname, + apr_text_header *body) { int propid; const dav_hooks_liveprop *hooks; @@ -903,7 +905,7 @@ } } -void dav_prop_validate(dav_prop_ctx *ctx) +DAV_DECLARE_NONSTD(void) dav_prop_validate(dav_prop_ctx *ctx) { dav_propdb *propdb = ctx->propdb; apr_xml_elem *prop = ctx->prop; @@ -994,7 +996,7 @@ } } -void dav_prop_exec(dav_prop_ctx *ctx) +DAV_DECLARE_NONSTD(void) dav_prop_exec(dav_prop_ctx *ctx) { dav_propdb *propdb = ctx->propdb; dav_error *err = NULL; @@ -1060,7 +1062,7 @@ } } -void dav_prop_commit(dav_prop_ctx *ctx) +DAV_DECLARE_NONSTD(void) dav_prop_commit(dav_prop_ctx *ctx) { dav_elem_private *priv = ctx->prop->priv; @@ -1077,7 +1079,7 @@ } } -void dav_prop_rollback(dav_prop_ctx *ctx) +DAV_DECLARE_NONSTD(void) dav_prop_rollback(dav_prop_ctx *ctx) { dav_error *err = NULL; dav_elem_private *priv = ctx->prop->priv; Index: modules/dav/main/util_lock.c =================================================================== --- modules/dav/main/util_lock.c (revision 155344) +++ modules/dav/main/util_lock.c (revision 155345) @@ -42,8 +42,9 @@ ** dav_lock_get_activelock: Returns a containing ** an activelock element for every item in the lock_discovery tree */ -const char *dav_lock_get_activelock(request_rec *r, dav_lock *lock, - dav_buffer *pbuf) +DAV_DECLARE(const char *) dav_lock_get_activelock(request_rec *r, + dav_lock *lock, + dav_buffer *pbuf) { dav_lock *lock_scan; const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); @@ -159,11 +160,11 @@ ** lockinfo XML element, then populates a dav_lock structure ** with its contents. */ -dav_error * dav_lock_parse_lockinfo(request_rec *r, - const dav_resource *resource, - dav_lockdb *lockdb, - const apr_xml_doc *doc, - dav_lock **lock_request) +DAV_DECLARE(dav_error *) dav_lock_parse_lockinfo(request_rec *r, + const dav_resource *resource, + dav_lockdb *lockdb, + const apr_xml_doc *doc, + dav_lock **lock_request) { apr_pool_t *p = r->pool; dav_error *err; @@ -285,9 +286,10 @@ ** all children, bounded by depth. ** ### assume request only contains one lock */ -dav_error * dav_add_lock(request_rec *r, const dav_resource *resource, - dav_lockdb *lockdb, dav_lock *lock, - dav_response **response) +DAV_DECLARE(dav_error *) dav_add_lock(request_rec *r, + const dav_resource *resource, + dav_lockdb *lockdb, dav_lock *lock, + dav_response **response) { dav_error *err; int depth = lock->depth; @@ -485,8 +487,8 @@ ** ### We've already crawled the tree to ensure everything was locked ** by us; there should be no need to incorporate a rollback. */ -int dav_unlock(request_rec *r, const dav_resource *resource, - const dav_locktoken *locktoken) +DAV_DECLARE(int) dav_unlock(request_rec *r, const dav_resource *resource, + const dav_locktoken *locktoken) { int result; dav_lockdb *lockdb; @@ -674,7 +676,8 @@ ** ** Returns DAV_RESOURCE_ERROR if an error occurs. */ -int dav_get_resource_state(request_rec *r, const dav_resource *resource) +DAV_DECLARE(int) dav_get_resource_state(request_rec *r, + const dav_resource *resource) { const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); @@ -732,11 +735,11 @@ return DAV_RESOURCE_NULL; } -dav_error * dav_notify_created(request_rec *r, - dav_lockdb *lockdb, - const dav_resource *resource, - int resource_state, - int depth) +DAV_DECLARE(dav_error *) dav_notify_created(request_rec *r, + dav_lockdb *lockdb, + const dav_resource *resource, + int resource_state, + int depth) { dav_error *err; Index: modules/dav/main/mod_dav.c =================================================================== --- modules/dav/main/mod_dav.c (revision 155344) +++ modules/dav/main/mod_dav.c (revision 155345) @@ -212,27 +212,27 @@ return conf->provider; } -const dav_hooks_locks *dav_get_lock_hooks(request_rec *r) +DAV_DECLARE(const dav_hooks_locks *) dav_get_lock_hooks(request_rec *r) { return dav_get_provider(r)->locks; } -const dav_hooks_propdb *dav_get_propdb_hooks(request_rec *r) +DAV_DECLARE(const dav_hooks_propdb *) dav_get_propdb_hooks(request_rec *r) { return dav_get_provider(r)->propdb; } -const dav_hooks_vsn *dav_get_vsn_hooks(request_rec *r) +DAV_DECLARE(const dav_hooks_vsn *) dav_get_vsn_hooks(request_rec *r) { return dav_get_provider(r)->vsn; } -const dav_hooks_binding *dav_get_binding_hooks(request_rec *r) +DAV_DECLARE(const dav_hooks_binding *) dav_get_binding_hooks(request_rec *r) { return dav_get_provider(r)->binding; } -const dav_hooks_search *dav_get_search_hooks(request_rec *r) +DAV_DECLARE(const dav_hooks_search *) dav_get_search_hooks(request_rec *r) { return dav_get_provider(r)->search; } @@ -648,7 +648,7 @@ } /* ### move to dav_util? */ -int dav_get_depth(request_rec *r, int def_depth) +DAV_DECLARE(int) dav_get_depth(request_rec *r, int def_depth) { const char *depth = apr_table_get(r->headers_in, "Depth"); Index: modules/dav/main/std_liveprop.c =================================================================== --- modules/dav/main/std_liveprop.c (revision 155344) +++ modules/dav/main/std_liveprop.c (revision 155345) @@ -169,22 +169,25 @@ NULL, /* patch_rollback */ }; -int dav_core_find_liveprop(const dav_resource *resource, - const char *ns_uri, const char *name, - const dav_hooks_liveprop **hooks) +DAV_DECLARE_NONSTD(int) dav_core_find_liveprop( + const dav_resource *resource, + const char *ns_uri, const char *name, + const dav_hooks_liveprop **hooks) { return dav_do_find_liveprop(ns_uri, name, &dav_core_liveprop_group, hooks); } -void dav_core_insert_all_liveprops(request_rec *r, - const dav_resource *resource, - dav_prop_insert what, apr_text_header *phdr) +DAV_DECLARE_NONSTD(void) dav_core_insert_all_liveprops( + request_rec *r, + const dav_resource *resource, + dav_prop_insert what, + apr_text_header *phdr) { (void) dav_core_insert_prop(resource, DAV_PROPID_resourcetype, what, phdr); } -void dav_core_register_uris(apr_pool_t *p) +DAV_DECLARE_NONSTD(void) dav_core_register_uris(apr_pool_t *p) { /* register the namespace URIs */ dav_register_liveprop_group(p, &dav_core_liveprop_group); Index: modules/dav/main/providers.c =================================================================== --- modules/dav/main/providers.c (revision 155344) +++ modules/dav/main/providers.c (revision 155345) @@ -27,7 +27,7 @@ ap_register_provider(p, DAV_PROVIDER_GROUP, name, "0", provider); } -const dav_provider * dav_lookup_provider(const char *name) +DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name) { return ap_lookup_provider(DAV_PROVIDER_GROUP, name, "0"); } Index: modules/dav/main/util.c =================================================================== --- modules/dav/main/util.c (revision 155344) +++ modules/dav/main/util.c (revision 155345) @@ -159,8 +159,9 @@ ** If NULL is returned, then an error occurred with parsing the URI or ** the URI does not match the current server. */ -dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r, - int must_be_absolute) +DAV_DECLARE(dav_lookup_result) dav_lookup_uri(const char *uri, + request_rec * r, + int must_be_absolute) { dav_lookup_result result = { 0 }; const char *scheme; @@ -287,7 +288,8 @@ */ /* validate that the root element uses a given DAV: tagname (TRUE==valid) */ -int dav_validate_root(const apr_xml_doc *doc, const char *tagname) +DAV_DECLARE(int) dav_validate_root(const apr_xml_doc *doc, + const char *tagname) { return doc->root && doc->root->ns == APR_XML_NS_DAV_ID && @@ -295,7 +297,8 @@ } /* find and return the (unique) child with a given DAV: tagname */ -apr_xml_elem *dav_find_child(const apr_xml_elem *elem, const char *tagname) +DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem, + const char *tagname) { apr_xml_elem *child = elem->first_child; @@ -461,7 +464,7 @@ * Seconds-xxx and Infinity time values. We assume that they do. * In addition, for now, that's all we understand, too. */ -time_t dav_get_timeout(request_rec *r) +DAV_DECLARE(time_t) dav_get_timeout(request_rec *r) { time_t now, expires = DAV_TIMEOUT_INFINITE; @@ -1402,10 +1405,13 @@ ** On error, return appropriate HTTP_* code, and log error. If a multi-stat ** error is necessary, response will point to it, else NULL. */ -dav_error * dav_validate_request(request_rec *r, dav_resource *resource, - int depth, dav_locktoken *locktoken, - dav_response **response, int flags, - dav_lockdb *lockdb) +DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r, + dav_resource *resource, + int depth, + dav_locktoken *locktoken, + dav_response **response, + int flags, + dav_lockdb *lockdb) { dav_error *err; int result; @@ -1623,7 +1629,8 @@ * Sets ltl to a locktoken_list of all positive locktokens in header, * else NULL if no If-header, or no positive locktokens. */ -dav_error * dav_get_locktoken_list(request_rec *r, dav_locktoken_list **ltl) +DAV_DECLARE(dav_error *) dav_get_locktoken_list(request_rec *r, + dav_locktoken_list **ltl) { dav_error *err; dav_if_header *if_header; @@ -1693,9 +1700,9 @@ * If there were any headers in the request which require a Vary header * in the response, add it. */ -void dav_add_vary_header(request_rec *in_req, - request_rec *out_req, - const dav_resource *resource) +DAV_DECLARE(void) dav_add_vary_header(request_rec *in_req, + request_rec *out_req, + const dav_resource *resource) { const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(in_req); @@ -1779,7 +1786,7 @@ } /* see mod_dav.h for docco */ -dav_error *dav_auto_checkout( +DAV_DECLARE(dav_error *) dav_auto_checkout( request_rec *r, dav_resource *resource, int parent_only, @@ -1925,7 +1932,7 @@ } /* see mod_dav.h for docco */ -dav_error *dav_auto_checkin( +DAV_DECLARE(dav_error *) dav_auto_checkin( request_rec *r, dav_resource *resource, int undo,