Documentation
NAVAL-SEM v0.8
Open-source structural equation modelling desktop application. PLS-SEM and CB-SEM
in a self-contained GUI — no R, no SPSS licence required.
v0.8.0
FastAPI · Python
semopy · NumPy · pandas
CC BY-NC-ND 4.0
Windows · macOS · Linux
- FIMIX-PLS — finite mixture segmentation detecting unobserved heterogeneity (EM algorithm, AIC/BIC/EN)
- PLS-POS — prediction-oriented segmentation with distance-based residual assignment
- Gaussian Copula — endogeneity correction for non-normal predictors (Park & Gupta 2012)
- PDF Report Export — single-click APA-style report from any completed run (
POST /export/pdf)
- Centralised versioning —
app/version.py injected from git tag at CI build time
- CI/CD pipeline simplified — sync-to-master step removed; all 3 platform builds now complete cleanly
Quick Start
1 · Launch the server
Shell
# From the extracted release folder
uvicorn app.main:app --reload --port 8000
# Or use the bundled launcher
python launcher.py
2 · POST your first model
All analysis endpoints accept multipart/form-data with a file upload (CSV / XLSX / SAV) and a model string in lavaan syntax.
cURL — minimal PLS-SEM run
curl -X POST http://localhost:8000/run \
-F "file=@data.csv" \
-F "model=Y =~ y1 + y2 + y3
X =~ x1 + x2 + x3
Y ~ X" \
-F "algorithm=pls" \
-F "bootstrap_n=500"
3 · Stream live logs (SSE)
JavaScript
const runId = crypto.randomUUID();
const es = new EventSource(`/logs/${runId}`);
es.onmessage = (e) => {
const d = JSON.parse(e.data);
if (d.done) { es.close(); return; }
console.log(d.level, d.msg);
};
// Then POST /run with run_id in the form body
formData.append("run_id", runId);
Algorithms
All analysis endpoints that accept an algorithm parameter support three estimators:
pls
Partial Least Squares SEM
- Default for all endpoints
- Small-to-medium samples
- Non-normal data
- Exploratory research
- Composite-based fit
cb
Covariance-Based SEM
- Theory-confirming
- Normal distribution assumed
- Full CFI / TLI / RMSEA
- n ≥ 200 recommended
- ML estimator via semopy
wls
Weighted Least Squares
- Ordinal / Likert data
- Robust to non-normality
- DWLS / WLSMV variant
- Categorical indicators
lavaan Syntax
NAVAL-SEM parses a lavaan-compatible model string. Three operator types are supported:
| Operator | Meaning | Example |
=~ | Measurement (reflective loading) | EXO =~ x1 + x2 + x3 |
~ | Structural regression path | ENO ~ EXO + MOD |
~~ | Residual covariance / variance | y2 ~~ y4 |
Interaction terms
Use the * operator inside a structural path to specify moderation. The engine auto-creates the mean-centred product column.
Moderation syntax
# Standard moderation: X*M on outcome Y
Y ~ X + M + X*M
X =~ x1 + x2 + x3
M =~ m1 + m2 + m3
Y =~ y1 + y2 + y3
Auto reverse scoring
Prefix any indicator name with r (e.g. rx3) when the column x3 exists in the dataset but rx3 does not. The server applies (max + min) − value automatically before fitting.
Reverse-scored indicator
SatisfactionLV =~ sat1 + sat2 + rsat3 + sat4
# rsat3 will be auto-reverse-scored from sat3
⚠
Multi-target residual covariance shorthand (y2 ~~ y4 + y6) is automatically expanded to individual pairs by the engine. However, write them individually for clarity in production models.
Core API
POST /run
Fit a full SEM model. Returns path coefficients, loadings, fit indices, validity metrics, and optionally bootstrap CIs. Generates a SHA-256 reproducibility fingerprint.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | CSV, XLSX, or SAV dataset |
| modelrequired | string | — | lavaan syntax string |
| algorithmoptional | string | pls | pls | cb | wls |
| bootstrap_noptional | int | 0 | Bootstrap resamples (0 = no bootstrap, max 20 000) |
| missingoptional | string | listwise | listwise | mean |
| run_idoptional | string | auto UUID | Client-supplied ID for SSE log streaming |
Returns → ModelResult
Key fields in the response JSON:
| Field | Type | Notes |
| algorithm | string | Estimator used |
| n_obs | int | Rows used after missing-data handling |
| converged | bool | Optimisation converged |
| parameters | PathParameter[] | All =~, ~, ~~ rows with estimates, SE, z, p, CI |
| fit | FitIndices | CFI, TLI, RMSEA, SRMR, χ², AIC, BIC, AVE, CR, α |
| vif | VIFEntry[] | null | Collinearity — VIF < 5 acceptable, < 3.3 strict |
| f2 | F2Entry[] | null | Cohen's f² for each predictor |
| indirect | IndirectResult | null | Populated when bootstrap_n > 0 |
| outer_weights | OuterWeightEntry[] | null | Bootstrap outer weights |
| fingerprint | string | null | SHA-256 reproducibility hash |
| summary | ModelSummary | null | High-level digest for UI panels (v0.7) |
| warnings | string[] | Non-fatal notices |
POST /bootstrap
Run standalone bootstrap without re-fitting the full model. Useful for extending an existing /run result with CIs post-hoc.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | CSV, XLSX, or SAV |
| modelrequired | string | — | lavaan syntax |
| bootstrap_noptional | int | 500 | Resamples (max 20 000) |
| algorithmoptional | string | pls | Estimator |
| missingoptional | string | listwise | Missing-data strategy |
POST /indirect
Decompose indirect (mediation) effects for all variable pairs connected via paths of length ≥ 2. Returns bootstrap 95 % CIs and a total-effects matrix.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset |
| modelrequired | string | — | lavaan syntax |
| bootstrap_noptional | int | 500 | Bootstrap resamples for CIs |
| missingoptional | string | listwise | |
Returns → IndirectResult
| Field | Type | Notes |
| effects | IndirectEffect[] | One row per from→through→to chain with bootstrapped SE, CI, significance |
| total_effects | Dict[str, Dict[str, float]] | Matrix: total_effects[from_var][to_var] |
POST /predict
Predictive relevance suite: Stone-Geisser Q² (blindfolding), PLSpredict k-fold vs linear baseline, and CVPAT.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset |
| modelrequired | string | — | lavaan syntax |
| omission_distanceoptional | int | 7 | Blindfolding omission distance D |
| k_foldsoptional | int | 10 | Cross-validation folds for PLSpredict |
| missingoptional | string | listwise | |
POST /cmb
Common Method Bias marker variable analysis (Lindell & Whitney 2001). Requires a marker variable theoretically unrelated to your constructs.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset |
| modelrequired | string | — | lavaan syntax |
| marker_variablerequired | string | — | Column name of the marker variable |
| missingoptional | string | listwise | |
POST /mga
Multi-Group Analysis: per-group model fit, pairwise bootstrap path-difference CIs, and (for 2-group analyses) MICOM measurement invariance.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset (must contain grouping column) |
| modelrequired | string | — | lavaan syntax |
| grouping_variablerequired | string | — | Column name for group splits |
| algorithmoptional | string | pls | |
| bootstrap_noptional | int | 500 | Resamples for path-difference CIs |
| missingoptional | string | listwise | |
| run_idoptional | string | auto UUID | SSE tracking ID |
v0.7
POST /moderation
Moderation analysis via the product-of-composites approach.
Detects X*M interaction terms in the lavaan structural syntax and tests each one
by comparing R² with vs. without the interaction term (Δ R², Cohen's f²)
and computing bootstrap simple slopes at moderator = −1 SD, mean (0), +1 SD.
✦
Manifest-variable fallback: when the model contains no =~ measurement lines, NAVAL-SEM automatically switches to an OLS path for observed-variable moderation (no latent composites needed).
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset (CSV, XLSX, SAV) |
| modelrequired | string | — | lavaan syntax; must include at least one X*M term |
| algorithmoptional | string | pls | pls | cb | wls |
| bootstrap_noptional | int | 500 | Bootstrap resamples for β_interaction CIs and simple slopes |
| missingoptional | string | listwise | |
| run_idoptional | string | auto UUID | SSE tracking ID |
Returns → ModerationResult
| Field | Type | Notes |
| moderation_terms | ModerationTerm[] | One entry per detected X×M interaction |
| parameters | PathParameter[] | Full model parameters including interaction term |
| fit | FitIndices | Fit of the full (interaction-included) model |
| n_obs | int | Effective sample size |
| bootstrap_n | int | Actual resamples used |
| warnings | string[] | |
ModerationTerm fields
| Field | Type | Notes |
| iv / moderator / outcome | string | Variable names |
| interaction_col | string | Auto-created product column name (e.g. X_x_M) |
| beta_iv / beta_moderator / beta_interaction | float | Standardised path coefficients |
| ci_lower_95 / ci_upper_95 | float | null | Bootstrap percentile CI for β_interaction |
| significant | bool | True when CI excludes 0 |
| r2_with / r2_without / delta_r2 | float | R² comparison |
| f2_interaction | float | Cohen's f² = Δ R² / (1 − R²_with) |
| simple_slopes | SimpleSlope[] | At W = −1 SD, 0, +1 SD |
Example syntax
# Test whether trust (TR) moderates innovation (IN) → satisfaction (SA)
SA ~ IN + TR + IN*TR
IN =~ in1 + in2 + in3
TR =~ tr1 + tr2 + tr3
SA =~ sa1 + sa2 + sa3
POST /ipma
Importance-Performance Map Analysis (Ringle & Sarstedt 2016; Hair et al. 2022 Ch. 7).
Computes for each predictor of a target latent variable:
Importance = total effect (direct + all indirect paths) and
Performance = mean composite score rescaled to 0–100.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset |
| modelrequired | string | — | lavaan syntax |
| target_lvrequired | string | — | Name of the outcome LV for which importance is computed |
| algorithmoptional | string | pls | |
| scale_minoptional | float | observed min | Theoretical scale minimum (e.g. 1 for Likert 1–5) |
| scale_maxoptional | float | observed max | Theoretical scale maximum (e.g. 5 for Likert 1–5) |
| missingoptional | string | listwise | |
| run_idoptional | string | auto UUID | |
Returns → IPMAResult
| Field | Type | Notes |
| target_lv | string | The outcome LV specified |
| entries | IPMAEntry[] | Sorted by importance descending |
| scale_min / scale_max | float | Scale range actually used for 0–100 rescaling |
| algorithm | string | |
| warnings | string[] | Emitted when scale range is inferred from data |
IPMAEntry fields
| Field | Type | Notes |
| lv | string | Predictor construct name |
| importance | float | Total effect on target_lv |
| performance | float | 0–100 rescaled composite mean (clamped) |
ℹ
Pass scale_min and scale_max matching your survey instrument (e.g. 1 and 5 for a five-point Likert scale) for correct 0–100 performance rescaling. When omitted, NAVAL-SEM uses the observed data range and appends a warning.
POST /nca
Necessary Condition Analysis (Dul 2016, 2020).
Tests whether each predictor is a necessary (not merely sufficient) condition for an outcome.
Computes CE-FDH (staircase ceiling) and CR-FDH (regression ceiling) effect sizes
plus permutation-based significance.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset |
| modelrequired | string | — | lavaan syntax; all structural IV→DV pairs are tested |
| n_permutationsoptional | int | 1000 | Permutation samples for p-value (max 20 000) |
| missingoptional | string | listwise | |
| run_idoptional | string | auto UUID | |
Returns → NCAResult
| Field | Type | Notes |
| entries | NCAEntry[] | One per unique IV→DV pair |
| n_permutations | int | |
| warnings | string[] | Pairs skipped due to insufficient n |
NCAEntry fields
| Field | Type | Notes |
| iv / dv / n_obs | string / int | |
| ce_fdh_d / ce_fdh_label / ce_fdh_p | float / string / float | Staircase ceiling effect size and permutation p |
| cr_fdh_d / cr_fdh_label | float / string | Regression ceiling effect size |
| cr_fdh_slope / cr_fdh_intercept / cr_fdh_p | float | Regression ceiling line parameters |
| significant | bool | True when max(ce_p, cr_p) < 0.05 |
| scatter_x / scatter_y | float[] | Sampled scatter plot coordinates (≤ 200 pts) |
| ceiling_x / ceiling_y | float[] | CE-FDH staircase coordinates (≤ 100 pts) |
NCA Effect Size Benchmarks (Dul 2016)
| d | Label |
| < 0.10 | negligible |
| 0.10 – 0.29 | small |
| 0.30 – 0.49 | medium |
| ≥ 0.50 | large |
Utilities
GET /logs/{run_id}
Server-Sent Events stream for a running analysis. Open immediately after submitting any endpoint that returns a run_id. The stream emits JSON objects and terminates with a done packet.
Stream events
| Event type | Fields | Notes |
| log entry | t, level, msg | level = step | info | ok | warn | error |
| done | done: true, fingerprint, audit | Stream closes after this |
Stream auto-closes after 4 hours; results continue in background.
GET /fingerprint/{run_id}
Retrieve the full SHA-256 audit record for a completed run. The fingerprint covers model syntax hash, data hash (SHA-256 of sorted column hashes), algorithm, environment versions, and key fit metrics.
Returns 404 if run_id is unknown; 425 if the run is still in progress.
POST /upload/preview
Parse an uploaded file and return column names, row count, first 5 rows, and dtype map — without running any analysis. Useful for validating uploads before model submission.
| Returns | Type | Notes |
| columns | string[] | All column names |
| n_rows | int | Total row count |
| preview | object[] | First 5 rows as records |
| dtypes | Dict[str, str] | pandas dtype per column |
GET /health
{ "status": "ok", "version": "0.7.1" }
Reference
Schemas
All response models are Pydantic v2 classes. Key schemas:
PathParameter
One row per model parameter (measurement loading, structural path, or covariance). std_error, z_value, and p_value are null for ~~ rows.
PathParameter
lhs str
op str =~ | ~ | ~~
rhs str
estimate float
std_estimate float?
std_error float?
z_value float?
p_value float?
ci_lower / ci_upper float?
significant bool
FitIndices
cfi / tli float?
rmsea float?
rmsea_ci_lower/upper float?
srmr float?
chi_square / df / p_value float?
aic / bic float?
r_squared Dict?
ave / composite_reliability Dict?
cronbach_alpha Dict?
fornell_larcker Dict?
cfi_good / rmsea_good / srmr_good bool?
IndirectEffect
from_var / to_var str
through str[] mediator chain
indirect_effect float
bs_se float?
ci_lower_95 / ci_upper_95 float?
significant bool?
F2Entry
lhs / rhs str
r2_full / r2_reduced float
f2 float ΔR²/(1−R²_full)
effect str negligible–large
Q2Entry (v0.5)
lv str endogenous LV
q2 float 1 − SSE/SSO
sse / sso float
omission_distance int
predictive_relevance str
HTMTEntry
construct_a / b str
htmt float
acceptable bool HTMT < 0.90
Fit Thresholds
Verdict flags set automatically by the engine:
| Index | Acceptable | Good | Field |
| CFI | ≥ 0.90 | ≥ 0.95 | cfi_acceptable / cfi_good |
| TLI (NNFI) | ≥ 0.90 | ≥ 0.95 | tli_acceptable / tli_good |
| RMSEA | ≤ 0.08 | ≤ 0.06 | rmsea_acceptable / rmsea_good |
| SRMR | — | ≤ 0.08 | srmr_good |
| AVE | ≥ 0.50 | — | per-LV in fit.ave |
| Composite Reliability | ≥ 0.70 | ≥ 0.80 | fit.composite_reliability |
| Cronbach's α | ≥ 0.70 | — | fit.cronbach_alpha |
| VIF | < 5.0 | < 3.3 (PLS strict) | vif[].acceptable |
| HTMT | < 0.90 | < 0.85 | htmt[].acceptable |
Effect Sizes
Cohen's f² (structural paths)
| f² | Label |
| < 0.02 | negligible |
| 0.02 – 0.14 | small |
| 0.15 – 0.34 | medium |
| ≥ 0.35 | large |
Stone-Geisser Q² (predictive relevance)
| Q² | Label |
| ≤ 0 | none |
| 0 – 0.25 | small |
| 0.25 – 0.50 | medium |
| ≥ 0.50 | large |
NCA Effect Size d (Dul 2016)
| d | Label |
| < 0.10 | negligible |
| 0.10 – 0.29 | small |
| 0.30 – 0.49 | medium |
| ≥ 0.50 | large |
v0.8 — New
POST /fimix
FIMIX-PLS (Finite Mixture PLS) detects unobserved heterogeneity by running an
Expectation-Maximisation algorithm over PLS-SEM path weights to identify latent segments
with distinct structural coefficient profiles. Reference: Hahn et al. 2002; Ringle et al. 2010.
✦
Segment selection: run with k = 2 to 5 and compare AIC3 / CAIC / relative entropy (EN ≥ 0.5 indicates acceptable separation).
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset (CSV, XLSX, SAV) |
| modelrequired | string | — | lavaan syntax (PLS-SEM) |
| n_segmentsrequired | int | — | Number of segments k (2–5) |
| max_iteroptional | int | 100 | EM iterations before convergence |
| seedoptional | int | 42 | Random seed for reproducibility |
| missingoptional | string | listwise | |
| run_idoptional | string | auto UUID | |
Returns → FIMIXResult
| Field | Type | Notes |
| n_segments | int | k as requested |
| segments | FIMIXSegment[] | One entry per segment |
| aic / bic / aic3 / caic | float | Information criteria for model selection |
| entropy | float | Relative entropy EN (0–1; ≥ 0.5 recommended) |
| n_obs | int | Effective sample size |
| warnings | string[] | |
FIMIXSegment fields
| Field | Type | Notes |
| segment_id | int | 1-indexed |
| size / size_pct | int / float | Observations assigned to this segment |
| path_coefficients | dict[str, float] | Segment-specific β values keyed by "lhs~rhs" |
| r_squared | dict[str, float] | R² per endogenous construct in this segment |
| posterior_probs | float[] | Per-observation membership probability |
v0.8 — New
POST /pos
PLS Prediction-Oriented Segmentation (PLS-POS) assigns observations to segments
by minimising within-segment residuals iteratively — no distributional assumptions required.
Reference: Becker et al. 2013.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset (CSV, XLSX, SAV) |
| modelrequired | string | — | lavaan syntax (PLS-SEM) |
| n_segmentsrequired | int | — | Number of segments k (2–5) |
| max_iteroptional | int | 100 | |
| seedoptional | int | 42 | |
| missingoptional | string | listwise | |
| run_idoptional | string | auto UUID | |
Returns → POSResult
| Field | Type | Notes |
| n_segments | int | |
| segments | POSSegment[] | One entry per segment |
| converged | bool | Whether assignment stabilised before max_iter |
| iterations | int | Actual iterations run |
| n_obs | int | |
| warnings | string[] | |
POSSegment fields
| Field | Type | Notes |
| segment_id | int | 1-indexed |
| size / size_pct | int / float | |
| path_coefficients | dict[str, float] | Segment-specific β values |
| loadings | dict[str, float] | Outer loadings for this segment |
| r_squared | dict[str, float] | R² per endogenous construct |
| observation_ids | int[] | 0-indexed row numbers assigned to this segment |
v0.8 — New
POST /gaussian-copula
The Gaussian Copula approach (Park & Gupta 2012; Hult et al. 2018) corrects for
endogeneity arising from non-normal, non-elliptical predictor distributions by augmenting the
structural model with copula terms derived from the empirical CDF of each non-normal predictor.
✦
Precondition: non-normality of the predictor is a necessary condition — normally distributed predictors cannot form valid copula terms. NAVAL-SEM screens automatically using Henze-Zirkler and skewness tests.
Form Parameters
| Field | Type | Default | Description |
| filerequired | File | — | Dataset (CSV, XLSX, SAV) |
| modelrequired | string | — | lavaan syntax |
| algorithmoptional | string | pls | |
| bootstrap_noptional | int | 500 | Bootstrap resamples for copula coefficient CIs |
| significanceoptional | float | 0.05 | α threshold for non-normality test |
| missingoptional | string | listwise | |
| run_idoptional | string | auto UUID | |
Returns → GaussianCopulaResult
| Field | Type | Notes |
| corrections | CopulaCorrection[] | One entry per endogenous path corrected |
| screened_predictors | dict[str, bool] | Non-normality test result per predictor |
| n_obs | int | |
| bootstrap_n | int | |
| warnings | string[] | |
CopulaCorrection fields
| Field | Type | Notes |
| lhs / rhs | string | Outcome and predictor construct names |
| copula_coef | float | Copula term coefficient in augmented model |
| ci_lower_95 / ci_upper_95 | float | null | Bootstrap percentile CI |
| significant | bool | True when CI excludes 0 — endogeneity confirmed |
| original_coef / corrected_coef | float | Path coefficient before and after correction |
| f2_correction | float | Cohen's f² for endogeneity increment |
v0.8 — New
POST /export/pdf
Generate a publication-ready PDF report from any completed run.
The report covers measurement model validity, structural path estimates,
bootstrapped confidence intervals, model fit indices, and any advanced analysis
results (FIMIX, PLS-POS, Gaussian Copula, IPMA, NCA) that were included in the run.
Tables follow APA 7th edition formatting conventions.
Form Parameters
| Field | Type | Default | Description |
| run_idrequired | string | — | UUID of the completed run to export |
| include_advancedoptional | bool | true | Include FIMIX / PLS-POS / Copula / IPMA / NCA sections if present |
| paperoptional | string | A4 | A4 | Letter |
Response
| Header | Value |
| Content-Type | application/pdf |
| Content-Disposition | attachment; filename="naval-sem-{run_id}.pdf" |
Example — cURL
curl -X POST http://localhost:8000/export/pdf \
-F "run_id=abc-123" \
--output report.pdf
Changelog
v0.8
- FIMIX-PLS: EM-based finite mixture segmentation, k=2–5, AIC/BIC/AIC3/CAIC/EN, segment-specific path coefficients and R²
- PLS-POS: prediction-oriented segmentation via iterative residual-based assignment
- Gaussian Copula: endogeneity correction for non-normal predictors (Park & Gupta 2012), bootstrap CIs, f² effect size
- PDF Report Export: APA-style publication-ready PDF via
POST /export/pdf
- Centralised versioning:
app/version.py single source of truth, CI-injected from git tag
- CI/CD: sync-to-master step removed from release workflow; all platform builds clean
v0.7
- Moderation: product-of-composites, OLS fallback for manifest models, bootstrap simple slopes at −1 SD / 0 / +1 SD, Δ R², Cohen's f²
- IPMA: total-effect importance, 0–100 rescaled performance, configurable theoretical scale range
- NCA: CE-FDH staircase ceiling, CR-FDH regression ceiling, permutation p-values, scatter / ceiling coordinates for frontend rendering
- Moderated Mediation (Hayes Models 7, 14, 58/59): IMM with bootstrap CI, conditional indirect effects at 3 moderator levels
- ModelSummary digest in
/run response: structural path table, construct validity table, verdicts
- Auto reverse-scoring via
r-prefix convention (auto_reverse_score)
- Residual covariance expansion fix (TC-52): multi-target
~~ shorthand correctly split into individual pairs
- Reproducibility fingerprint (SHA-256) in all
/run responses and accessible via GET /fingerprint/{run_id}
v0.6
- Higher-Order Constructs: repeated-indicator and two-stage approaches
- GitHub Actions CI/CD: version injected from git tags
- Full-width results drawer with live SSE logging
- MGA and MICOM tabs wired in UI
- SourceForge distribution connector via native GitHub integration
v0.5
- Predictive relevance suite: Q², PLSpredict, CVPAT (
POST /predict)
- Common Method Bias marker variable analysis (
POST /cmb)
- Outer weights bootstrap with t-statistics
v0.4
- Multi-Group Analysis with MICOM (
POST /mga)
- Indirect effects decomposition (
POST /indirect)
- VIF collinearity table, Cohen's f² for all structural paths
v0.3
- HTMT discriminant validity (
POST /htmt)
- AVE, composite reliability, Cronbach's α in FitIndices
- Fornell-Larcker criterion matrix
≤ v0.2
- Initial public release: PLS-SEM / CB-SEM / WLS via semopy backend
- Bootstrap standalone (
POST /bootstrap)
- CSV / XLSX / SAV parser, SSE log stream,
/health endpoint
- PyInstaller distributable for Windows, macOS, Linux