# Tracking System Architecture ## Overview The tracking system provides comprehensive analytics for user interactions across onboarding, settings, and other flows. It features source-based field filtering, multi-funnel support, and extensible adapter architecture to prevent tracking loops and enable granular event control. It monitors WordPress data stores rather than adding code to frontend components, ensuring comprehensive coverage of all state changes regardless of their source (user actions, API responses, system updates) while maintaining clean separation of concerns. ## File Organization ``` src/ ├── services/ │ └── tracking/ │ ├── registry.js # Central funnel registration │ ├── subscription-manager.js # Store subscription management │ ├── utils/ │ │ ├── field-config-helpers.js # Field config helpers & utilities │ │ └── utils.js # Core tracking utilities │ ├── services/ │ │ └── funnel-tracking.js # Funnel tracking service │ ├── adapters/ # Tracking destination adapters │ │ ├── woocommerce-tracks.js # WooCommerce Tracks integration │ │ └── console-logger.js # Console output │ ├── funnels/ # Funnel-specific configurations │ │ └── onboarding.js # Onboarding funnel config & translations │ ├── index.js # Main exports │ └── init.js # Initialization system ├── data/ # Redux stores │ ├── tracking/ # Dedicated tracking store │ │ ├── actions.js # Field source tracking actions │ │ ├── reducer.js # Field source state management │ │ ├── selectors.js # Field source data access │ │ └── index.js # Store initialization │ ├── onboarding/ # Clean business logic store │ │ ├── actions.js # Pure business actions │ │ ├── reducer.js # Clean business logic │ │ ├── selectors.js # Business data access │ │ └── hooks.js # Enhanced hooks with tracking │ ├── common/ # Clean business logic store │ │ ├── actions.js # Pure business actions │ │ ├── reducer.js # Clean business logic │ │ ├── selectors.js # Business data access │ │ └── hooks.js # Enhanced hooks with tracking │ └── utils.js # Enhanced createHooksForStore └── components/ # Enhanced to pass tracking sources └── **/*.js # Form components updated with source attribution ``` ## 1. Registry System (`registry.js`) Manages funnel registration and coordinates multiple tracking concerns without conflicts. ### Store-to-Funnel Mapping ```javascript // Registry maintains mapping of stores to multiple funnels const trackingRegistry = { funnels: {}, storeToFunnel: {}, // Store name -> array of funnel IDs instances: {}, }; // Example mapping: { 'wc/paypal/onboarding': ['ppcp_onboarding', 'settings_funnel'], 'wc/paypal/common': ['ppcp_onboarding', 'other_funnel'], } ``` ### Usage ```javascript import { registerFunnel } from '../services/tracking/registry'; registerFunnel('ppcp_onboarding', onboardingConfig); ``` ## 2. Subscription Manager (`subscription-manager.js`) Creates **unified subscriptions** to WordPress data stores and routes changes to **multiple relevant funnels**. ### Single Subscription, Multiple Funnels ```javascript class SubscriptionManager { constructor() { this.storeSubscriptions = {}; // ONE subscription per store this.storeRegistrations = {}; // MULTIPLE funnel registrations per store } ensureStoreSubscription(storeName) { if (this.storeSubscriptions[storeName]) { return; // Skip if subscription already exists } // Create unified subscription for all funnels tracking this store const unsubscribe = wp.data.subscribe(() => { this.handleStoreChange(storeName); }); } } ``` ### Benefits - **One subscription per store** regardless of funnel count - **Independent funnel logic** - each has its own rules and conditions - **Isolated state** - each funnel tracks its own previous values ## 3. Tracking Store (`data/tracking/`) Separate Redux store handles all field source information. ### State Structure ```javascript // { storeName: { fieldName: { source, timestamp } } } { 'wc/paypal/onboarding': { 'step': { source: 'user', timestamp: 1638360000000 }, 'isCasualSeller': { source: 'user', timestamp: 1638360000000 } }, 'wc/paypal/common': { 'useSandbox': { source: 'system', timestamp: 1638360000000 } } } ``` ## 4. Universal Hook System (`data/utils.js`) `createHooksForStore` makes **any Redux store** tracking-compatible. ```javascript // Works with ANY store const { usePersistent, useTransient } = createHooksForStore('wc/paypal/any-store'); // In components const [ field, setField ] = usePersistent('fieldName'); setField(newValue, 'user'); // Automatically tracked if configured ``` ## 5. Source-Based Field Filtering Field-level rules define which change sources trigger tracking events. ```javascript // Configuration fieldRules: { step: { allowedSources: ['user', 'system'] }, // Track all changes isCasualSeller: { allowedSources: ['user'] }, // Only user changes } // Usage setIsCasualSeller(true, 'user'); // Tracked setIsCasualSeller(false); // Filtered out (no source) ``` **Source Types:** - `'user'` - Direct user interactions - `'system'` - System-initiated changes ## 6. Funnel Configuration Uses `FunnelConfigBuilder` pattern: ```javascript // src/services/tracking/funnels/onboarding.js export const config = FunnelConfigBuilder.createBasicFunnel(FUNNEL_ID, { debug: false, adapters: ['woocommerce-tracks'], eventPrefix: 'ppcp_onboarding', trackingCondition: { store: 'wc/paypal/common', selector: 'merchant', field: 'isConnected', expectedValue: false } }) .addEvents(EVENTS) .addTranslations(TRANSLATIONS) .addStore('wc/paypal/onboarding', [ createFieldTrackingConfig('step', 'persistent', { rules: { allowedSources: ['user', 'system'] } }) ]) .build(); ``` ## 7. Initialization (`init.js`) Required before store registration: ```javascript import { registerFunnel } from './registry'; export function initializeTrackingFunnels() { if (initialized) return; registerFunnel(ONBOARDING_FUNNEL_ID, onboardingConfig); initialized = true; } // Auto-initialize initializeTrackingFunnels(); ``` ## 8. Store Registration Stores register with funnels in their index files: ```javascript // src/data/onboarding/index.js import { addStoreToFunnel } from '../../services/tracking'; export const initStore = () => { const store = createReduxStore(STORE_NAME, { reducer, actions, selectors }); register(store); addStoreToFunnel(STORE_NAME, ONBOARDING_FUNNEL_ID); return Boolean(wp.data.select(STORE_NAME)); }; ``` ## Adding Tracking to New Stores ### 1. Create Clean Business Store ```javascript // actions.js export const setPersistent = (prop, value) => ({ type: ACTION_TYPES.SET_PERSISTENT, payload: { [prop]: value }, }); // reducer.js const reducer = createReducer(defaultTransient, defaultPersistent, { [ACTION_TYPES.SET_PERSISTENT]: (state, payload) => changePersistent(state, payload), }); ``` ### 2. Create Tracking-Enabled Hooks ```javascript // hooks.js import { createHooksForStore } from '../utils'; export const { usePersistent, useTransient } = createHooksForStore('wc/paypal/your-store'); ``` ### 3. Register Store ```javascript // index.js addStoreToFunnel(STORE_NAME, 'your-funnel-id'); ``` ### 4. Configure Funnel ```javascript // funnels/your-funnel.js export const config = FunnelConfigBuilder.createBasicFunnel('your-funnel', { debug: false, adapters: ['console'], }) .addStore('wc/paypal/your-store', [ createFieldTrackingConfig('yourField', 'persistent', { rules: { allowedSources: ['user'] } }) ]) .addTranslations({ yourField: (oldValue, newValue, metadata, trackingService) => { trackingService.sendToAdapters('your_event_name', { new_value: newValue, old_value: oldValue }); } }) .build(); ``` ## Multi-Funnel Example Multiple funnels tracking the same store: ```javascript // Both register interest in same store addStoreToFunnel('wc/paypal/onboarding', 'ppcp_onboarding'); addStoreToFunnel('wc/paypal/onboarding', 'settings_funnel'); // Results in ONE subscription, TWO registrations with different rules: storeRegistrations = { 'wc/paypal/onboarding': [ { funnelId: 'ppcp_onboarding', fieldRules: { step: {allowedSources: ['user', 'system']} }, trackingCondition: { field: 'isConnected', expectedValue: false }, previousValues: {} // Separate per funnel }, { funnelId: 'settings_funnel', fieldRules: { step: {allowedSources: ['user']} }, trackingCondition: { field: 'isConnected', expectedValue: true }, previousValues: {} // Separate per funnel } ] } ``` ## Debugging ### Enable Debug Mode ```javascript export const config = FunnelConfigBuilder.createBasicFunnel('funnel', { debug: true, }); ``` ### Inspect Tracking Store ```javascript const trackingStore = wp.data.select('wc/paypal/tracking'); console.log('All sources:', trackingStore.getAllFieldSources()); console.log('Store sources:', trackingStore.getStoreFieldSources('wc/paypal/onboarding')); ``` ### Check Registry Status ```javascript import { getTrackingStatus, getMultiFunnelStores } from '../services/tracking'; console.log('Status:', getTrackingStatus()); console.log('Multi-funnel stores:', getMultiFunnelStores()); ``` ## Event Schema Events follow pattern: `ppcp_{funnel}_{action}_{object}` Examples: - `ppcp_onboarding_account_type_select` - `ppcp_onboarding_step_forward` - `ppcp_settings_payment_method_toggle`
تصویر کتاب

کتاب داستان‌ها

مجموعه‌ای نفیس از لحظاتی در گذر زمان، شامل عکس‌هایی از لویی فکنشتاین، پل استرند و آساهاچی کونو.

هم‌اکنون برای پیش‌سفارش در دسترس است.

(()=>{var t={31:(t,e,a)=>{var o=a(456),n=jQuery,i=function(){var t=this;this.params=[],this.modal=new o,this.modal.onStop=function(e){t.onStop(e)}};i.prototype.setParams=function(t){this.params=Ai1wm.Util.list(t)},i.prototype.start=function(t,e){var a=this;if(0===(e=e||0)&&this.stopExport(!1),!this.isExportStopped()){n(window).on("beforeunload",function(){return ai1wmke_locale.stop_resetting_your_website}),this.setStatus({type:"info",message:ai1wm_locale.preparing_to_export});var o=this.params.concat({name:"secret_key",value:ai1wm_export.secret_key});t&&(o=o.concat(Ai1wm.Util.list(t))),n.ajax({url:ai1wm_export.ajax.url,type:"POST",dataType:"json",data:o,dataFilter:function(t){return Ai1wm.Util.json(t)}}).done(function(){a.getStatus()}).done(function(t){t&&a.run(t)}).fail(function(n){var i=1e3*e;try{var r=Ai1wm.Util.json(n.responseText);if(r){var s=JSON.parse(r).errors.pop();if(s.message)return a.stopExport(!0),void a.setStatus({type:"error",title:ai1wm_locale.unable_to_export,message:s.message,nonce:Ai1wm.Util.findValueByName(o,"storage")})}}catch(t){}if(e>=5)return a.stopExport(!0),void a.setStatus({type:"error",title:ai1wm_locale.unable_to_export,message:ai1wm_locale.unable_to_start_the_export,nonce:Ai1wm.Util.findValueByName(o,"storage")});e++,setTimeout(a.start.bind(a,t,e),i)})}},i.prototype.run=function(t,e){var a=this;e=e||0,this.isExportStopped()||n.ajax({url:ai1wm_export.ajax.url,type:"POST",dataType:"json",data:t,dataFilter:function(t){return Ai1wm.Util.json(t)}}).done(function(t){t&&a.run(t)}).fail(function(o){var n=1e3*e;try{var i=Ai1wm.Util.json(o.responseText);if(i){var r=JSON.parse(i).errors.pop();if(r.message)return a.stopExport(!0),void a.setStatus({type:"error",title:ai1wm_locale.unable_to_export,message:r.message,nonce:Ai1wm.Util.findValueByName(t,"storage")})}}catch(t){}if(e>=5)return a.stopExport(!0),void a.setStatus({type:"error",title:ai1wm_locale.unable_to_export,message:ai1wm_locale.unable_to_run_the_export,nonce:Ai1wm.Util.findValueByName(t,"storage")});e++,setTimeout(a.run.bind(a,t,e),n)})},i.prototype.clean=function(t,e){var a=this;0===(e=e||0)&&this.stopExport(!0),this.setStatus({type:"info",message:ai1wm_locale.please_wait_stopping_the_export});var o=this.params.concat({name:"secret_key",value:ai1wm_export.secret_key}).concat({name:"priority",value:300}).concat({name:"ai1wm_export_cancel",value:1});t&&(o=o.concat(Ai1wm.Util.list(t))),n.ajax({url:ai1wm_export.ajax.url,type:"POST",dataType:"json",data:o,dataFilter:function(t){return Ai1wm.Util.json(t)}}).done(function(){n(window).off("beforeunload"),a.modal.destroy()}).fail(function(n){var i=1e3*e;try{var r=Ai1wm.Util.json(n.responseText);if(r){var s=JSON.parse(r).errors.pop();if(s.message)return a.stopExport(!0),void a.setStatus({type:"error",title:ai1wm_locale.unable_to_export,message:s.message,nonce:Ai1wm.Util.findValueByName(o,"storage")})}}catch(t){}if(e>=5)return a.stopExport(!0),void a.setStatus({type:"error",title:ai1wm_locale.unable_to_export,message:ai1wm_locale.unable_to_stop_the_export,nonce:Ai1wm.Util.findValueByName(o,"storage")});e++,setTimeout(a.clean.bind(a,t,e),i)})},i.prototype.getStatus=function(){var t=this;this.isExportStopped()||(this.statusXhr=n.ajax({url:ai1wm_export.status.url,type:"GET",dataType:"json",cache:!1,dataFilter:function(t){return Ai1wm.Util.json(t)}}).done(function(e){if(e)switch(t.setStatus(e),e.type){case"done":case"error":case"download":return void n(window).off("beforeunload")}setTimeout(t.getStatus.bind(t),3e3)}).fail(function(){setTimeout(t.getStatus.bind(t),3e3)}))},i.prototype.setStatus=function(t){this.modal.render(t)},i.prototype.onStop=function(t){this.clean(t)},i.prototype.stopExport=function(t){try{t&&this.statusXhr&&this.statusXhr.abort()}finally{this.isStopped=t}},i.prototype.isExportStopped=function(){return this.isStopped},t.exports=i},213:function(t,e,a){var o,n,i;n=[],void 0===(i="function"==typeof(o=function(){"use strict";function e(t,e){return void 0===e?e={autoBom:!1}:"object"!=typeof e&&(console.warn("Deprecated: Expected third argument to be a object"),e={autoBom:!e}),e.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob(["\ufeff",t],{type:t.type}):t}function o(t,e,a){var o=new XMLHttpRequest;o.open("GET",t),o.responseType="blob",o.onload=function(){p(o.response,e,a)},o.onerror=function(){console.error("could not download file")},o.send()}function n(t){var e=new XMLHttpRequest;e.open("HEAD",t,!1);try{e.send()}catch(t){}return 200<=e.status&&299>=e.status}function i(t){try{t.dispatchEvent(new MouseEvent("click"))}catch(a){var e=document.createEvent("MouseEvents");e.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),t.dispatchEvent(e)}}var r="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof a.g&&a.g.global===a.g?a.g:void 0,s=r.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),p=r.saveAs||("object"!=typeof window||window!==r?function(){}:"download"in HTMLAnchorElement.prototype&&!s?function(t,e,a){var s=r.URL||r.webkitURL,p=document.createElement("a");e=e||t.name||"download",p.download=e,p.rel="noopener","string"==typeof t?(p.href=t,p.origin===location.origin?i(p):n(p.href)?o(t,e,a):i(p,p.target="_blank")):(p.href=s.createObjectURL(t),setTimeout(function(){s.revokeObjectURL(p.href)},4e4),setTimeout(function(){i(p)},0))}:"msSaveOrOpenBlob"in navigator?function(t,a,r){if(a=a||t.name||"download","string"!=typeof t)navigator.msSaveOrOpenBlob(e(t,r),a);else if(n(t))o(t,a,r);else{var s=document.createElement("a");s.href=t,s.target="_blank",setTimeout(function(){i(s)})}}:function(t,e,a,n){if((n=n||open("","_blank"))&&(n.document.title=n.document.body.innerText="downloading..."),"string"==typeof t)return o(t,e,a);var i="application/octet-stream"===t.type,p=/constructor/i.test(r.HTMLElement)||r.safari,l=/CriOS\/[\d]+/.test(navigator.userAgent);if((l||i&&p||s)&&"undefined"!=typeof FileReader){var c=new FileReader;c.onloadend=function(){var t=c.result;t=l?t:t.replace(/^data:[^;]*;/,"data:attachment/file;"),n?n.location.href=t:location=t,n=null},c.readAsDataURL(t)}else{var u=r.URL||r.webkitURL,d=u.createObjectURL(t);n?n.location=d:location.href=d,n=null,setTimeout(function(){u.revokeObjectURL(d)},4e4)}});r.saveAs=p.saveAs=p,t.exports=p})?o.apply(e,n):o)||(t.exports=i)},456:t=>{var e=jQuery,a=function(){var t=this;this.error=function(a){var o=e("
"),n=e("
"),i=e("

"),r=e("

").html(a.message),s=e("
"),p=e("").addClass("ai1wm-title-red").text(a.title),l=e('').on("click",function(){t.destroy()});if(l.append(ai1wm_locale.close_export),s.append(l),i.append(p),n.append(i).append(r),a.nonce){var c=e('');c.text(ai1wm_locale.view_error_log_button),c.prop("href",ai1wm_export.storage.url+"/"+ai1wm_export.error_log.pattern.replace("%s",a.nonce)),n.append(e("
").append(c))}o.append(n).append(s),t.modal.html(o).show(),t.modal.trigger("focus"),t.overlay.show()},this.info=function(a){var o=e("
"),n=e("
"),i=e("

"),r=e("

").html(a.message),s=e("
"),p=e(''),l=e('').on("click",function(){l.attr("disabled","disabled"),t.onStop()});l.append(' '+ai1wm_locale.stop_export),s.append(l),i.append(p),n.append(i).append(r),o.append(n).append(s),t.modal.html(o).show(),t.modal.trigger("focus"),t.overlay.show()},this.done=function(a){var o=e("
"),n=e("
"),i=e("

"),r=e("

").html(a.message),s=e("
"),p=e("").addClass("ai1wm-title-green").text(a.title),l=e('').on("click",function(){t.destroy()});l.append(ai1wm_locale.close_export),s.append(l),i.append(p),n.append(i).append(r),o.append(n).append(s),t.modal.html(o).show(),t.modal.trigger("focus"),t.overlay.show()},this.download=function(a){var o=e("
"),n=e("
"),i=e("

").html(a.message),r=e("
"),s=e('').on("click",function(){t.destroy()}),p=e(".ai1wm-menu-count");p.text(+p.text()+1),p.text()>1?p.prop("title",ai1wm_locale.backups_count_plural.replace("%d",p.text())):(p.removeClass("ai1wm-menu-hide"),p.prop("title",ai1wm_locale.backups_count_singular.replace("%d",p.text()))),s.append(ai1wm_locale.close_export),r.append(s),n.append(i),o.append(n).append(r),t.modal.html(o).show(),t.modal.trigger("focus"),t.overlay.show()},this.overlay=e('
'),this.modal=e(''),e("body").append(this.overlay).append(this.modal)};a.prototype.render=function(t){switch(e(document).trigger("ai1wm-export-status",t),t.type){case"error":this.error(t);break;case"info":this.info(t);break;case"done":this.done(t);break;case"download":this.download(t)}},a.prototype.destroy=function(){this.modal.hide(),this.overlay.hide()},t.exports=a},647:()=>{var t;(t=jQuery).fn.ai1wm_find_replace=function(){return t(this).on("click",function(e){e.preventDefault();var a=t("#ai1wm-queries > li:first").clone();a.find("input").val(""),a.find(".ai1wm-query-find-text").html("<text>"),a.find(".ai1wm-query-replace-text").html("<another-text>"),t("#ai1wm-queries > li").removeClass("ai1wm-open"),t(a).addClass("ai1wm-open"),t("#ai1wm-queries").append(a),t(a).ai1wm_query(),t(a).find("p:first").on("click",function(){t(this).parent().toggleClass("ai1wm-open")})}),this}},705:()=>{var t;(t=jQuery).fn.ai1wm_query=function(){var e=t(this).find("input.ai1wm-query-find-input"),a=t(this).find("input.ai1wm-query-replace-input"),o=t(this).find("small.ai1wm-query-find-text"),n=t(this).find("small.ai1wm-query-replace-text");return e.on("change paste input keypress keydown keyup",function(){var e=t(this).val().length>0?t(this).val():"";o.text(e)}),a.on("change paste input keypress keydown keyup",function(){var e=t(this).val().length>0?t(this).val():"";n.text(e)}),this}}},e={};function a(o){var n=e[o];if(void 0!==n)return n.exports;var i=e[o]={exports:{}};return t[o].call(i.exports,i,i.exports,a),i.exports}a.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return a.d(e,{a:e}),e},a.d=(t,e)=>{for(var o in e)a.o(e,o)&&!a.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),a.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";var t=a(213),e=a(705),o=a(647),n=a(31);jQuery(document).ready(function(e){var a=new n;e("#ai1wm-export-file").on("click",function(t){if(e("#ai1wm-encrypt-backups").is(":checked")){var o=e("#ai1wm-backup-encrypt-password"),n=e("#ai1wm-backup-encrypt-password-confirmation");if(!o.val().length)return o.parent().addClass("ai1wm-has-error"),o.focus(),!1;if(o.val()!==n.val())return n.parent().addClass("ai1wm-has-error"),n.focus(),!1}var i=Ai1wm.Util.random(12),r=Ai1wm.Util.form("#ai1wm-export-form").concat({name:"storage",value:i}).concat({name:"file",value:1});a.setParams(r),a.start(),t.preventDefault()}),e(document).on("click",".ai1wm-modal-container .ai1wm-direct-download",function(a){a.preventDefault();var o=e(this).prop("download"),n={secret_key:ai1wm_export.secret_key,archive:o},i=new XMLHttpRequest;i.addEventListener("readystatechange",function(){2===i.readyState&&200===i.status||3===i.readyState||4===i.readyState&&(i.status<400?(0,t.saveAs)(i.response,Ai1wm.Util.basename(o)):alert(ai1wm_locale.archive_browser_download_error))}),i.responseType="blob";var r=new FormData;for(var s in n)r.append(s,n[s]);i.open("post",ai1wm_export.download.url),i.send(r)}),e(".ai1wm-accordion > .ai1wm-title").on("click",function(){e(this).parent().toggleClass("ai1wm-active")}),e("#ai1wm-add-new-replace-button").ai1wm_find_replace(),e(".ai1wm-expandable > p:first, .ai1wm-expandable > h4:first, .ai1wm-expandable > div.ai1wm-button-main").on("click",function(){e(this).parent().toggleClass("ai1wm-open")}),e(".ai1wm-query").ai1wm_query(),e(".ai1wm-toggle-password-visibility").on("click",function(){return e(this).toggleClass("ai1wm-icon-eye ai1wm-icon-eye-blocked"),e(this).prev().prop("type",function(t,e){return"text"===e?"password":"text"}),!1}),e("#ai1wm-encrypt-backups").on("click",function(){e(".ai1wm-encrypt-backups-passwords-toggle").toggle()}),e("#ai1wm-backup-encrypt-password").on("keyup",function(){var t=e(this),a=e("#ai1wm-backup-encrypt-password-confirmation");t.val()!==a.val()&&a.parent().addClass("ai1wm-has-error"),t.val().length&&t.parent().removeClass("ai1wm-has-error")}),e("#ai1wm-backup-encrypt-password-confirmation").on("keyup",function(){var t=e(this);e("#ai1wm-backup-encrypt-password").val()!==t.val()?t.parent().addClass("ai1wm-has-error"):t.parent().removeClass("ai1wm-has-error")})}),a.g.Ai1wm=jQuery.extend({},a.g.Ai1wm,{Query:e,FindReplace:o,Export:n})})()})(); ایپاس – نمایشگاه بین المللی لوازم و تجهیزات پلیسی،امنیتی و ایمنی .fs-notice[data-id^=clone_resolution_options_notice]{color:inherit!important;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{margin-bottom:0;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-bottom:0;margin-top:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width:750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;flex:auto;margin:5px;padding:10px 10px 15px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;line-height:1.5em;padding:2px}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-left:10px;margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{background:#fee;border:1px solid #d3135a;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}.fs-notice[data-id=temporary_duplicate_notice] a{position:relative}.fs-notice[data-id=temporary_duplicate_notice] a:focus{box-shadow:none}.fs-notice[data-id=temporary_duplicate_notice] a.disabled{color:gray}.fs-notice[data-id=temporary_duplicate_notice] a .fs-ajax-spinner{bottom:0;left:8px;margin-left:100%;position:absolute;right:0;top:-1px}

بیست و دومین نمایشگاه بین المللی IPAS 2025

زمان برگزاری 21 الی 24 مهرماه 1404 در مصلی امام خمینی(ره)-سالن شبستان

مدت زمان باقیمانده به افتتاح

مدت زمان مانده به افتتاحیه

نمایشگاه افتتاح و درحال برگزاری می باشد.

اخبار

اخبار نمایشگاه, مقالات

۱۷ تیر ۱۴۰۳

بیست و یکمین نمایشگاه بین المللی ایپاس 2024

اخبار نمایشگاه, مقالات

۱۱ تیر ۱۴۰۳

اولین جلسه کمیته هماهنگی نمایشگاه IPAS 2024

اولین جلسه کمیته هماهنگی نمایشگاه با حضور مدیرعامل محترم بنیاد تعاون فراجا

اخبار نمایشگاه, مقالات

۹ خرداد ۱۴۰۳

سومین جلسه کمیته برنامه ریزی نمایشگاه ا ایپاس 2024

سومین جلسه کمیته برنامه ریزی نمایشگاه با حضور مدیرعامل محترم شرکت ناجی پاس و اعضای کمیته و مدعوین خاص در روز چهارشنبه مورخ 09/03/1403 راس ساعت 08:30 صبح در محل جلسات شرکت ناجی پاس برگزار گردید

تور مجازی نمایشگاه IPAS2024

نمایشگاه بین‌المللی IPAS یکی از مهم‌ترین رویدادهای صنعتی و تجاری در حوزه امنیت، حفاظت و ایمنی در سطح منطقه و جهان به‌شمار می‌رود. این نمایشگاه که هر ساله در تهران برگزار می‌شود، محلی برای معرفی و نمایش آخرین دستاوردها و تکنولوژی‌های نوین در زمینه تجهیزات امنیتی، سیستم‌های حفاظتی و راهکارهای ایمنی است.

اسپانسرها

ویدئو معرفی

[aparat id="dqpn762"]

سایر حامیان IPAS2025

گالری تصاویر

درباره IPAS

نمایشگاه بین‌المللی  IPAS یکی از مهم‌ترین رویدادهای صنعتی و تجاری در حوزه امنیت، حفاظت و ایمنی در سطح منطقه و جهان به‌شمار می‌رود. این نمایشگاه که هر ساله در تهران برگزار می‌شود، محلی برای معرفی و نمایش آخرین دستاوردها و تکنولوژی‌های نوین در زمینه تجهیزات امنیتی، سیستم‌های حفاظتی و راهکارهای ایمنی است.

IPAS با گرد هم آوردن فعالان برجسته این حوزه از سراسر جهان، فرصتی بی‌نظیر برای تبادل دانش و تجارب، شناسایی فرصت‌های تجاری جدید و برقراری ارتباطات تجاری پایدار فراهم می‌کند. این رویداد نه تنها بستری برای نمایش توانمندی‌های داخلی در عرصه جهانی است، بلکه به ارتقاء سطح دانش و آگاهی متخصصان و علاقه‌مندان نیز کمک شایانی می‌کند

نمایشگاه بین المللی IPAS رویدادی است که با هدف نمایش، معرفی و عرضه کالاها و خدمات و لوازم و تجهیزات پلیسی، امنیتی و ایمنی انجام می شود و مجموعه ای از خدمات مشتمل بر خدمات مدیریتی، بازاریابی، گردشگری، حمل و نقل، امور گمرگی، بیمه، بانکداری، تبلیغات، فنی و مهندسی، برگزاری همایش و کارگاهای آموزشی است که با هدف توسعه مبادلات بازرگانی در حوزه کالا و خدمات در سطوح ملی و بین المللی، توسعه صادرات، کسب درآمد ارزی، تبادل و انتقال و گسترش دانش فنی و فناوری های پیشرفته، توسعه سرمایه گذاری، بسط مناسبات اقتصادی، فرهنگی و اجتماعی، آموزش همگانی، حمایت از تولید ملی و توسعه اشتغال و… را شامل می گردد.